When trying to change the state of TEntry1 which is controlled by the button in the upper right instead of changing the state of TEntry1 it creates a new window that has TEntry1 greyed out and all variable inputs blank.
The GUI was generated by PAGE
PAGE exports to 2 files, I've combined the 2 for this question
The window to the left is the program running as desired, the button will initially say start, then clicking on it will will switch to running mode and changes the text to stop. It is also supposed to grey out the entry widget, but instead creates a new window with the entry widget greyed out
I believe the issue is happening in disableentry(): with how the attribute is called
def disableentry():
print("disableentry() start")
root = tk.Tk()
Toplevel1(root).TEntry1.configure(state='disabled')
import sys
import threading
import tkinter as tk
import tkinter.ttk as ttk
def destroy_Toplevel1():
thread0.stop()
class Toplevel1:
def __init__(self, top=None):
'''This class configures and populates the toplevel window.
top is the toplevel containing window.'''
_bgcolor = '#d9d9d9' # X11 color: 'gray85'
_fgcolor = '#000000' # X11 color: 'black'
_compcolor = '#d9d9d9' # X11 color: 'gray85'
_ana1color = '#d9d9d9' # X11 color: 'gray85'
_ana2color = '#ececec' # Closest X11 color: 'gray92'
self.style = ttk.Style()
if sys.platform == "win32":
self.style.theme_use('winnative')
self.style.configure('.',background=_bgcolor)
self.style.configure('.',foreground=_fgcolor)
self.style.configure('.',font="TkDefaultFont")
self.style.map('.',background=
[('selected', _compcolor), ('active',_ana2color)])
top.geometry("460x406 660 210")
top.minsize(120, 1)
top.maxsize(3844, 1061)
top.resizable(0, 0)
top.title("PAGE GUI")
top.configure(background="#d9d9d9")
top.configure(highlightbackground="#d9d9d9")
top.configure(highlightcolor="black")
self.TEntry1 = ttk.Entry(top)
self.TEntry1.place(x=76, y=41, height=21, width=137)
self.TEntry1.configure(takefocus="")
self.TEntry1.configure(cursor="ibeam")
self.TEntry1.configure(textvariable=entry1text)
self.Label1 = tk.Label(top)
self.Label1.place(x=21, y=41, height=31, width=38)
self.Label1.configure(activebackground="#f9f9f9")
self.Label1.configure(activeforeground="black")
self.Label1.configure(background="#d9d9d9")
self.Label1.configure(disabledforeground="#a3a3a3")
self.Label1.configure(foreground="#000000")
self.Label1.configure(highlightbackground="#d9d9d9")
self.Label1.configure(highlightcolor="black")
self.Label1.configure(text='''IP 1''')
self.Button1 = tk.Button(top)
self.Button1.place(x=330, y=41, height=24, width=107)
self.Button1.configure(activebackground="#ececec")
self.Button1.configure(activeforeground="#000000")
self.Button1.configure(background="#d9d9d9")
self.Button1.configure(disabledforeground="#a3a3a3")
self.Button1.configure(foreground="#000000")
self.Button1.configure(highlightbackground="#d9d9d9")
self.Button1.configure(highlightcolor="black")
self.Button1.configure(pady="0")
self.Button1.configure(textvariable=button_text)
self.Button1.configure(command=guicontrols.start_stop)
class guisetup():
def set_Tk_var():
global running_status
running_status = tk.IntVar()
running_status.set(0)
global button_text
button_text = tk.StringVar()
button_text.set('Start')
global entry1text
entry1text = tk.StringVar()
entry1text.set('')
def vp_start_gui():
global val, w, root
root = tk.Tk()
guisetup.set_Tk_var()
top = Toplevel1 (root)
root.mainloop()
class guithread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self
def run(self):
guisetup.vp_start_gui()
class guicontrols():
def disableentry():
print("disableentry() start")
root = tk.Tk()
Toplevel1(root).TEntry1.configure(state='disabled')
def start_stop():
print('PLA_support.start_stop')
if (running_status.get() == 1):
button_text.set("Stop")
running_status.set(0)
guicontrols.disableentry()
else:
button_text.set("Start")
running_status.set(1)
sys.stdout.flush()
if __name__ == '__main__':
thread0 = guithread()
thread0.start()
CodePudding user response:
Here is a cleaned-up version of your code. I put everything to do with the window into one class: App
, so that all the variables can be accessed properly.
import sys
import threading
import tkinter as tk
import tkinter.ttk as ttk
class App(tk.Tk):
"""The main window."""
def __init__(self):
tk.Tk.__init__(self)
# Set the theme
_bgcolor = '#d9d9d9' # X11 color: 'gray85'
_fgcolor = '#000000' # X11 color: 'black'
_compcolor = '#d9d9d9' # X11 color: 'gray85'
_ana1color = '#d9d9d9' # X11 color: 'gray85'
_ana2color = '#ececec' # Closest X11 color: 'gray92'
self.style = ttk.Style()
if sys.platform == "win32":
self.style.theme_use('winnative')
self.style.configure('.', background=_bgcolor)
self.style.configure('.', foreground=_fgcolor)
self.style.configure('.', font="TkDefaultFont")
self.style.map(
'.',
background=[('selected', _compcolor), ('active',_ana2color)]
)
self.geometry("460x406 660 210")
self.minsize(120, 1)
self.maxsize(3844, 1061)
self.resizable(0, 0)
self.title("PAGE GUI")
self.configure(background="#d9d9d9")
self.configure(highlightbackground="#d9d9d9")
self.configure(highlightcolor="black")
# Running status
self.running_status = tk.IntVar()
self.running_status.set(1)
# Create the widgets
self.create_widgets()
def create_widgets(self):
"""Create the widgets and add them to the window."""
self.entry1text = tk.StringVar()
self.entry1text.set("")
self.TEntry1 = ttk.Entry(
self,
takefocus="",
cursor="xterm",
textvariable=self.entry1text
)
self.TEntry1.place(x=76, y=41, height=21, width=137)
# The label-
self.Label1 = tk.Label(
self,
activebackground="#f9f9f9",
activeforeground="black",
background="#d9d9d9",
disabledforeground="#a3a3a3",
foreground="#000000",
highlightbackground="#d9d9d9",
highlightcolor="black",
text="IP 1"
)
self.Label1.place(x=21, y=41, height=31, width=38)
# The button
self.button_text = tk.StringVar()
self.button_text.set('Start')
self.Button1 = tk.Button(
self,
activebackground="#ececec",
activeforeground="#000000",
background="#d9d9d9",
disabledforeground="#a3a3a3",
foreground="#000000",
highlightbackground="#d9d9d9",
highlightcolor="black",
pady="0",
textvariable=self.button_text,
command=self.start_stop
)
self.Button1.place(x=330, y=41, height=24, width=107)
def disable_entry(self):
self.TEntry1.config(state="disabled")
def enable_entry(self):
self.TEntry1.config(state="enabled")
def start_stop(self):
print('PLA_support.start_stop')
if (self.running_status.get() == 1):
self.button_text.set("Stop")
self.running_status.set(0)
self.disable_entry()
else:
self.button_text.set("Start")
self.running_status.set(1)
self.enable_entry()
class guithread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.app = App()
def run(self):
self.app.mainloop()
if __name__ == '__main__':
thread0 = guithread()
thread0.run()
I also put the widget arguments that were originally in tons of config()
functions as arguments for the widget classes themselves; it's better syntax.
I kept the threading and added a function that re-enables the entry when the user clicks the button. I also changed the line self.running_status.set(0)
after self.running_status = tkinter.IntVar()
to self.running_status.set(1)
. This fixes an error where, when the program first starts, you have to click the button twice before anything happens.
If something wasn't what you wanted, or if you have any questions or run into any problems, I'll be glad to help!