为了账号安全,请及时绑定邮箱和手机立即绑定

tkinter 类对象未定义

tkinter 类对象未定义

梦里花落0921 2023-10-05 16:45:02
我对 Python 相当陌生,这是我使用 tkinter 的第一个项目。我的整个项目运行良好,只有一个例外。我已将 tkinter 代码构建到一个类中,一切正常,但我不知道如何从类外部调用这些方法。当我在 main 中的以下行创建对象时,出现 NameError: name 'robotGUI' is not Definedclass botGUI:    def __init__(self):        #Init Code    def updateStatus(self):        #Code HererobotGUI = botGUI()如果我将变量“robotGUI”初始化为 None,代码就会运行,但是当我稍后尝试访问其方法之一时,我会收到 AttributeError: 'NoneType' object has no attribute 'doSomething'。似乎没有创建 robotsGUI 对象,但我不明白为什么。我到处搜索并找到了一些接近的答案,但没有任何与这个问题完全相关的答案。我有一些其他类在这个程序中运行得很好,所以我确信它与 tkinter 和它的内部主循环有关,只是无法确定它。这是我大大减少和简化的代码,显示了问题:#!/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)}")        
查看完整描述

2 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

self.window.mainloop()删除的呼叫botGUI.__init__(),然后您可以:

  • 创建以下实例botGUIrobotGUI = botGUI()

  • 创建线程并启动它

  • 称呼roboGUI.window.mainloop()

下面是修改后的代码:

#!/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)}")

        



#Main Task - Since tKinter is running in the main loop, all of the main loop code is moved to here

def 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 Handler

def 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()


查看完整回答
反对 回复 2023-10-05
?
心有法竹

TA贡献1866条经验 获得超5个赞

您必须在所有函数之外定义 robotsGUI,如下所示:


robotGUI = None

def 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)


查看完整回答
反对 回复 2023-10-05
  • 2 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信