I have some problems with Checkbutton in classes. They always return the start value. I am attaching the example code, in Main.py I create a window and a button to invoke my class with the checkbutton. In this second class (WindowProteins.py:) the check button does not work and always returns the same value
Main.py:
#tkinter import
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from tkinter.filedialog import askopenfile
from tkinter.messagebox import showinfo
import WindowProteins as wPr
#font
font_title = ('times', 18, 'bold')
font_subtitle = ('times', 14, 'bold')
def CreateProteins():
windowPr = wPr.ProteinsWindow()
windowPr.mainloop()
#create welcome window
def CreateWelcome():
#window
global window_welcome
window_welcome = tk.Tk()
window_welcome.geometry("400x300") # Size of the window
window_welcome.title('Main')
#button
btn_proteins = tk.Button(window_welcome, text='Proteins',
width=20,command = lambda:CreateProteins())
btn_proteins.grid(row=2,column=1)
window_welcome.mainloop() #Keep the window open
CreateWelcome()
WindowProteins.py:
#tkinter import
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from tkinter.filedialog import askopenfile
from tkinter.messagebox import showinfo
class ProteinsWindow(tk.Tk):
df = pd.DataFrame()
def __init__(self):
super().__init__()
# configure the root window
self.title('Proteins')
self.geometry('800x400')
#fonts
self.font_title=('times', 18, 'bold')
self.font_subtitle = ('times', 14, 'bold')
self.font_base = ('times', 11)
#Protein FDR checkboxes
self.var_chc_low = IntVar(value=1)
self.chc_low = tk.Checkbutton(self, text='Low',variable=self.var_chc_low, onvalue=1, offvalue=0, command=self.agreement_changed )
self.chc_low.grid(row=0,column=0, sticky='w')
self.chc_low.select()
def agreement_changed(self):
print(str(self.var_chc_low.get()))
how can i solve?
CodePudding user response:
You should use tk.Tk()
only to create main window. Other windows you should create using tk.Toplevel()
. And you should use only one mainloop()
because two loops (and two main windows) can make conflict when you try to get value.
Working code (as single file) with other changes
You may use BooleanVar()
and True/False
instead of IntVar()
and 1/0
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import filedialog
from tkinter.filedialog import askopenfile
from tkinter.messagebox import showinfo
import pandas as pd
# font
font_title = ('times', 18, 'bold')
font_subtitle = ('times', 14, 'bold')
# --- classes --- # PEP8: `CamelCaseNames`
class ProteinsWindow(tk.Toplevel):
def __init__(self):
super().__init__()
self.df = pd.DataFrame()
# configure the root window
self.title('Proteins')
self.geometry('800x400')
# fonts
self.font_title = ('times', 18, 'bold')
self.font_subtitle = ('times', 14, 'bold')
self.font_base = ('times', 11)
# Protein FDR checkboxes
self.var_chc_low = tk.BooleanVar(value=True)
self.chc_low = tk.Checkbutton(self, text='Low', variable=self.var_chc_low, onvalue=True, offvalue=False, command=self.agreement_changed)
self.chc_low.grid(row=0, column=0, sticky='w')
self.chc_low.select()
def agreement_changed(self):
print(self.var_chc_low.get())
# --- functions --- # PEP8: `lower_case_names`
def create_proteins():
window_pr = ProteinsWindow()
def create_welcome():
"""Create welcome window."""
# window
global window_welcome
window_welcome = tk.Tk()
window_welcome.geometry("400x300") # size of the window
window_welcome.title('Main')
# button
btn_proteins = tk.Button(window_welcome, text='Proteins', width=20, command=create_proteins)
btn_proteins.grid(row=2, column=1)
# keep the window open
window_welcome.mainloop()
# --- main ---
create_welcome()