在PythonTkinter应用程序中引用全局对象

2024-04-26 21:13:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试在一个pythonttkinter应用程序中更新一个标签,当另一个小部件被选中时。在

我创建了一个小工具,用来演示这个问题。该工具将创建一个顶部有标签的小GUI。此标签应显示所选框的编号。在

Image of tool

问题是,当鼠标点击选择一个方框编号时,该编号不会显示在顶部标签中。单击框号应该调用setSelected,它应该调用应用程序集标签(字符串)。但是,我收到错误“未定义全局名称'app'”

如何使对象“app”全局化?在

#!/usr/bin/env python
import Tkinter

def setSelected(string):
    app.setLabel(string)

class Gui():
    Boxes = []

    def __init__(self):
        self._root = Tkinter.Tk()
        self._root.protocol("WM_DELETE_WINDOW", self._applicationExit)
        self._string = Tkinter.StringVar()
        self.setLabel('None')
        self._label = Tkinter.Label(self._root, textvariable = self._string,
            width = 10)
        self._label.grid(row = 0, column = 0, padx = 5, pady = 5)
        self._createBoxOverview()
        self._root.mainloop()

    def _applicationExit(self, event = None):
        self._root.destroy()

    def _createBoxOverview(self):
        _frame = Tkinter.LabelFrame(self._root, text = 'Boxes')
        for _id in range(4):
            self.Boxes.append(Box(_frame, _id))
            self.Boxes[_id].grid(row = 0, column = _id)
        _frame.grid(row = 1, column = 0, padx = 5, pady = 5)

    def setLabel(self, string):
        self._string.set(string)

class Box(Tkinter.Label):
    def __init__(self, master, id):
        Tkinter.Label.__init__(self, master)
        self._id = str(id)
        self._text = Tkinter.StringVar()
        self._text.set(self._id)
        self.config(textvariable = self._text, width = 3)
        self.bind("<Button-1>", self._onSelect)

    def _onSelect(self, event):
        setSelected(self._id)

if __name__ == '__main__':
    app = Gui()

Tags: textselfidappstringinittkinterdef
1条回答
网友
1楼 · 发布于 2024-04-26 21:13:34

问题是,您正在创建rootTk()应用程序)并调用root.mainloop(),在__init__()内部,因此{}不会完全被创建,因为只有当您从__init__()返回时才会创建它,但是在关闭应用程序之前,您不会这样做。在

对于您的情况,最简单的解决方案是将root对象移出Gui()类。示例-

import Tkinter

def setSelected(string):
    app.setLabel(string)

class Gui():
    Boxes = []

    def __init__(self, root):
        self._root = root
        self._root.protocol("WM_DELETE_WINDOW", self._applicationExit)
        self._string = Tkinter.StringVar()
        self.setLabel('None')
        self._label = Tkinter.Label(self._root, textvariable = self._string,
            width = 10)
        self._label.grid(row = 0, column = 0, padx = 5, pady = 5)
        self._createBoxOverview()

    def _applicationExit(self, event = None):
        self._root.destroy()

    def _createBoxOverview(self):
        _frame = Tkinter.LabelFrame(self._root, text = 'Boxes')
        for _id in range(4):
            self.Boxes.append(Box(_frame, _id))
            self.Boxes[_id].grid(row = 0, column = _id)
        _frame.grid(row = 1, column = 0, padx = 5, pady = 5)

    def setLabel(self, string):
        self._string.set(string)

class Box(Tkinter.Label):
    def __init__(self, master, id):
        Tkinter.Label.__init__(self, master)
        self._id = str(id)
        self._text = Tkinter.StringVar()
        self._text.set(self._id)
        self.config(textvariable = self._text, width = 3)
        self.bind("<Button-1>", self._onSelect)

    def _onSelect(self, event):
        setSelected(self._id)

if __name__ == '__main__':
    root = Tkinter.Tk()
    app = Gui(root)
    root.mainloop()

相关问题 更多 >