简体   繁体   中英

Changing the widget on button press Tkinter (Python)

I am writing the code for a GUI that displays some text with Label and on button press, I want to change the text of my Label. Here is my code for making a widget.

def makeWidget(self):
    self.widgets = []
    widget1 = Label(self, width=50, height=20)
    widget1.config(text='There is going to be smth here!')
    widget1.pack(side=TOP, fill=BOTH)
    self.widgets.append(widget1)

I am calling this function in my __init__(self, parent=None) . And everything is working nice. But when I am pressing the button for which I am assigning the command of update

def update(self):
    self.widgets[0].config(text='Here text should change')

the Error is appearing

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python37-32\lib\tkinter\__init__.py", line 1702, in __call__
return self.func(*args)
File "C:/Users/User/PycharmProjects/untitled4/venv/main.py", line 17, in 
<lambda>
toolBar = [('Edit', lambda :(makeGui.update(root)), {'side': 'left'}),
File "C:\Users\User\PycharmProjects\untitled4\venv\Include\menu_toolbar.py", 
line 71, in update
self.widgets[0].config(text='Here text should change')
File "C:\Python37-32\lib\tkinter\__init__.py", line 2098, in __getattr__
return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'widgets'  

I initial thought that the rpoblem is becouse self.widget is not being saved in anywhere that is why tried to save it by self.widgets=[] Can someone help? How can I make changes in my widget with button press.

PS In case the problem is not in the places I have mentioned above, here is my full code:


This is my main.py :

from tkinter import *
from Include.menu_toolbar import makeGui
import time
root=Tk()
menuBar = [
    ('File', 0,
     [('Open', 0, lambda: 0),
      ('Quit', 0, sys.exit)]),
    ('Edit', 0,
     [('Add', 0, lambda: 0),
      ('Remove', 0, lambda: 0)]),
    ('Help', 0,
     [('About', 0, lambda: 0),
      ('Optins', 0, lambda: 0)])
    ]
toolBar = [('Edit', lambda :(makeGui.update(root)), {'side': 'left'}),
               ('Add', lambda: 0, {'side': 'left'}),
               ('Remove', lambda: 0, {'side': 'left'})
               ]

toolbarColor = '#3C3F41'
class LocalGuiMaker(makeGui):
    def start(self):
        self.menuBar = menuBar
        self.toolBar = toolBar
        self.toolbarColor = toolbarColor
LocalGuiMaker(root).mainloop()

This is my menu_toolbar.py :

from tkinter import * 
import sys, time

class makeGui(Frame):
    menuBar = []
    toolBar = []
    toolbarColor = 'white'
    def __init__(self, parent=None):
        Frame.__init__(self, parent)
        self.pack(expand=YES, fill=BOTH)
        self.start()
        self.makeMenuBar()
        self.makeToolBar()
        self.makeWidget()
    def makeMenuBar(self):
        menubar = Menu(self.master)
        self.master.config(menu=menubar)
        for (name, u_index, items) in self.menuBar:
            pulldown = Menu(menubar)
            self.addItems(pulldown, items)
            menubar.add_cascade(label=name, underline=u_index, menu=pulldown)

    def addItems(self, menu, items):
        for item in items:
            if item == 'separator':
                menu.add_separator({})
            elif type(item[2]) != list:
                menu.add_command(label=item[0],
                             underline=item[1],
                               command=item[2])
            else:
                pullover = Menu(menu)
                addItem(pullover, item[2])
                menu.add_cascade(label=item[0],
                               underline=item[1],
                               menu=pullover)

    def makeToolBar(self):
        toolbar = Frame(self, relief=SUNKEN, bd=2, bg=self.toolbarColor)
        toolbar.pack(side=BOTTOM, fill=X)
        for (name, command, place) in self.toolBar:
            Button(toolbar, text=name, command=command, fg='white', 
                    bg=self.toolbarColor).pack(place)
        clock = Label(toolbar, fg='white', bg=self.toolbarColor)
        clock.pack(side=RIGHT, expand=False, fill=Y)
        time1 = ''

        def tick():
            nonlocal time1
            time2 = time.strftime('%H:%M:%S')
            if time2 != time1:
                time1 = time2
                clock.config(text=time1)
            clock.after(200, tick)

        tick()


    def makeWidget(self):
        self.widgets = []
        widget1 = Label(self, width=50, height=20)
        widget1.config(text='There is going to be smth here!')
        widget1.pack(side=TOP, fill=BOTH)
        self.widgets.append(widget1)

    def update(self):
        self.widgets[0].config(text='Here text should change')


    def start(self):
        pass

The problem's in the creation of the toolbar

toolBar = [('Edit', lambda :(makeGui.update(root)), {'side': 'left'}),
               ('Add', lambda: 0, {'side': 'left'}),
               ('Remove', lambda: 0, {'side': 'left'})
               ]

And specifically makeGui.update(root) .

What you want the button to do is call the update method of the makeGui instance you create, but what you're doing is calling the update method on the makeGui class. The problem is you can't reference the makeGui instance at this point, since it doesn't exist yet.

Is there any reason for defining menuBar , toolBar and toolbarColor outside of the LocalGuiMaker class? It's already a simple wrapper around the makeGui class right? If you define them inside the start function, you can reference the class instance by using self :

class LocalGuiMaker(makeGui):
    def start(self):
        self.menuBar = [
                       ('File', 0,
                           [('Open', 0, lambda: 0), ('Quit', 0, sys.exit)]),
                       ('Edit', 0,
                           [('Add', 0, lambda: 0), ('Remove', 0, lambda: 0)]),
                       ('Help', 0,
                           [('About', 0, lambda: 0), ('Optins', 0, lambda: 0)])
                       ]
        self.toolBar = [
                       ('Edit', self.update, {'side': 'left'}),
                       ('Add', lambda: 0, {'side': 'left'}),
                       ('Remove', lambda: 0, {'side': 'left'})
                       ]

        self.toolbarColor = '#3C3F41'

LocalGuiMaker(root).mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM