猿问

tkinter 类对象未定义

我对 Python 相当陌生,这是我使用 tkinter 的第一个项目。我的整个项目运行良好,只有一个例外。我已将 tkinter 代码构建到一个类中,一切正常,但我不知道如何从类外部调用这些方法。


当我在 main 中的以下行创建对象时,出现 NameError: name 'robotGUI' is not Defined


class botGUI:

    def __init__(self):

        #Init Code


    def updateStatus(self):

        #Code Here


robotGUI = botGUI()

如果我将变量“robotGUI”初始化为 None,代码就会运行,但是当我稍后尝试访问其方法之一时,我会收到 AttributeError: 'NoneType' object has no attribute 'doSomething'。似乎没有创建 robotsGUI 对象,但我不明白为什么。


我到处搜索并找到了一些接近的答案,但没有任何与这个问题完全相关的答案。我有一些其他类在这个程序中运行得很好,所以我确信它与 tkinter 和它的内部主循环有关,只是无法确定它。

这是我大大减少和简化的代码,显示了问题:


#!/usr/bin/env python3


#Imports

import socket, select, errno, sys, queue, time, threading, cv2

from tkinter import *

from tkinter import font

from PIL import Image, ImageTk


#GUI

class botGUI:


    def __init__(self):


        #Create the Window Object and Setup the Window

        self.window = Tk()

        self.window.geometry("800x480+0+0")

        self.window.overrideredirect(True)

        self.window.fullScreenState = False


        #Code to Generate Gaphics Here .....        


        #Call Repeating Status Update Script and Start the Main Loop

        self.updateStatus()

        self.window.mainloop()    


    def updateStatus(self):


        #Code to Handle Updating Screen Objects Here ....    

        print("Update Status Running")


        #Set this function to be called again

        self.window.after(1000, lambda: self.updateStatus())

        


    def doSomething(self, myStr):


        #Code to change something on the screen ...

        print(f"Command: {str(myStr)}")


    def doSomethingElse(self, myStr):


        #Code to change something on the screen ...

        print(f"Command: {str(myStr)}")

        

梦里花落0921
浏览 86回答 2
2回答

饮歌长啸

self.window.mainloop()删除的呼叫botGUI.__init__(),然后您可以:创建以下实例botGUI:robotGUI = botGUI()创建线程并启动它称呼roboGUI.window.mainloop()下面是修改后的代码:#!/usr/bin/env python3#Importsimport socket, select, errno, sys, queue, time, threading, cv2from tkinter import *from tkinter import fontfrom PIL import Image, ImageTk#GUIclass botGUI:    def __init__(self):        #Create the Window Object and Setup the Window        self.window = Tk()        self.window.geometry("800x480+0+0")        self.window.overrideredirect(True)        self.window.fullScreenState = False        #Code to Generate Gaphics Here .....                #Call Repeating Status Update Script and Start the Main Loop        self.updateStatus()        #self.window.mainloop()        def updateStatus(self):        #Code to Handle Updating Screen Objects Here ....            print("Update Status Running")        #Set this function to be called again        self.window.after(1000, lambda: self.updateStatus())            def doSomething(self, myStr):        #Code to change something on the screen ...        print(f"Command: {str(myStr)}")    def doSomethingElse(self, myStr):        #Code to change something on the screen ...        print(f"Command: {str(myStr)}")        #Main Task - Since tKinter is running in the main loop, all of the main loop code is moved to heredef main_loop():    #global robotGUI    robotDataReceived = True #This is only for this posting    #Main Loop    while True:        #If Incoming Data from Robot, Get and Process It!        if robotDataReceived:            robotCmdHandler()                    #Anti Blocking Delay (Much shorter, set higher for this post)        time.sleep(2)#Robot Command Handlerdef robotCmdHandler():    #global robotGUI    #Code to get a command string and process it goes here .....    cmd = "dosomething"  #Temporary for this post    #Handle command    if (cmd == "dosomething"):        print("Processing Command")        robotGUI.doSomething("Do This")if __name__ == '__main__':    #Create GUI Object    robotGUI = botGUI()    #Create and Start Threads    t1 = threading.Thread(target=main_loop, name='t1')    t1.start()                # start the GUI main loop    robotGUI.window.mainloop()    #Wait until threads are finished    t1.join()

心有法竹

您必须在所有函数之外定义 robotsGUI,如下所示:robotGUI = Nonedef main_loop():     global robotGUI     robotDataReceived = True #This is only for this posting     #Main Loop     while True:         #If Incoming Data from Robot, Get and Process It!         if robotDataReceived:             robotCmdHandler()                 #Anti Blocking Delay (Much shorter, set higher for this post)         time.sleep(2)
随时随地看视频慕课网APP

相关分类

Python
我要回答