New instance of toplevel classes make overlapping widgets

2024/10/6 2:21:08

I'm generally new to python and tkinter. I've been programming maybe about a year or so, and I've just started to try to make each tkinter toplevel window its own class because I've heard that it's the right way to do it.

I'm making a program in which I have a treeview with a button to add contents to it. The button opens up a new window that allows the user to input the contents. The problem I'm having is when I have to instantiate the first window to update the treeview, it seems like it's doubling all of the widgets on the first window. This causes it to keep building up and it looks strange.

Is this normal or is there a better way to do it?

Thank you. I can post a picture or my code if necessary.

edit: shortened code

from tkinter import *
from tkinter import ttkclass MainWindow:Items = {'test': ['Material', '500']}def __init__(self, master):self.master = masterself.style = ttk.Style()self.style.configure('TLabel', font=12)ttk.Label(self.master, text="Items").grid(row=0, column=0, columnspan=3)self.frmItems = ttk.Frame(self.master)self.frmItems.grid(row=1, column=0, padx=5, pady=5, columnspan=3)self.treeItems = ttk.Treeview(self.frmItems, columns=(0, 1, 2))self.treeItems.column('#0', width=0, minwidth=0)self.treeItems.column(1, width=80)self.treeItems.column(2, width=80)self.treeItems.heading(0, text="Name")self.treeItems.heading(1, text="Type")self.treeItems.heading(2, text="Price")self.treeItems.grid(row=0, column=0)self.itemscroll = ttk.Scrollbar(self.frmItems, command=self.treeItems.yview)self.itemscroll.grid(row=0, column=1, sticky='ns')self.treeItems.config(yscrollcommand=self.itemscroll.set)ttk.Button(self.master, text="New", command=self.item_input_show).grid(row=2, column=0, padx=5, pady=5,sticky='e')ttk.Button(self.master, text="Edit").grid(row=2, column=1, padx=5, pady=5)ttk.Button(self.master, text="Remove").grid(row=2, column=2, padx=5, pady=5, sticky='w')def item_input_show(self):ItemInput(self.master)class ItemInput:def __init__(self, master):self.master = masterself.MainWindow = MainWindow(master)self.topItemInput = Toplevel(self.master)self.topItemInput.title("Input Item Properties")def main():root = Tk()MainWindow(root)root.mainloop()if __name__ == "__main__":main()
Answer

You are calling class MainWindow: every time you press the New Button. This is remaking all the widgets over and over. And they way you are creating the MainWindow is affecting how you can interact with MainWindow.

Change:

def main():root = Tk()MainWindow(root)root.mainloop()if __name__ == "__main__":main()

To:

 if __name__ == "__main__":root = Tk()main = MainWindow(root)root.mainloop()

Once you have made this change you are able to interact with the instance attributes and methods of main

Below is a modified version of your code. You will notice when you press the button I added to the TopLevel window it will print information from an atribute and method of main variable. It will also place some text in the entry box in the MainWindow.

from tkinter import *
from tkinter import ttkclass MainWindow:def __init__(self, master):self.master = masterself.btn = ttk.Button(self.master, text="New", command=self.item_input_show)self.btn.pack(side = TOP)self.entry = Entry(self.master)self.entry.pack(side = BOTTOM)self.numbers = 200def two_plus_x(self, x):math = 2 + xreturn mathdef item_input_show(self):ItemInput(self.master)class ItemInput:def __init__(self, master):self.master = masterself.topItemInput = Toplevel(master)self.btn = ttk.Button(self.topItemInput, text="Use method in MainWindow", command = self.do_something_from_main)self.btn.pack()def do_something_from_main(self):print(main.numbers)print(main.two_plus_x(10))main.entry.delete(0, END)main.entry.insert(0, "From ItemInput Class")# notice I removed def main(): as it was preventing us from interacting with the main variable.
if __name__ == "__main__":root = Tk()main = MainWindow(root)root.mainloop()
https://en.xdnf.cn/q/118998.html

Related Q&A

Regex End of Line and Specific Chracters

So Im writing a Python program that reads lines of serial data, and compares them to a dictionary of line codes to figure out which specific lines are being transmitted. I am attempting to use a Regul…

Is it possible to scrape webpage without using third-party libraries in python?

I am trying to understand how beautiful soup works in python. I used beautiful soup,lxml in my past but now trying to implement one script which can read data from given webpage without any third-party…

Different model performance evaluations by statsmodels and scikit-learn

I am trying to fit a multivariable linear regression on a dataset to find out how well the model explains the data. My predictors have 120 dimensions and I have 177 samples:X.shape=(177,120), y.shape=(…

Python to search CSV file and return relevant info

I have a csv file with information about some computers on our network. Id like to be able to type from the command line a quick line to bring me back the relevant items from the csv. In the format:$…

Remove all elements matching a predicate from a list in-place

How can I remove all elements matching a predicate from a list IN-PLACE? T = TypeVar("T")def remove_if(a: list[T], predicate: Callable[[T], bool]):# TODO: Fill this in.# Test: a = [1, 2, 3, …

Python-scriptlines required to make upload-files from JSON-Call

Lacking experience & routine for Python-programming. Borrowing examples from forums have made a script which successfully makes a JSON-cal (to Domoticz) and generates & prints the derived JSON-…

python pygame mask collision [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.Want to improve this question? Add details and clarify the problem by editing this post.Closed 4 years ago.The com…

How to find max average of values by converting list of tuples to dictionary?

I want to take average for all players with same name. I wrote following code. its showing index error whats the issue?Input: l = [(Kohli, 73), (Ashwin, 33), (Kohli, 7), (Pujara, 122),(Ashwin, 90)]Out…

Cannot pass returned values from function to another function in python

My goal is to have a small program which checks if a customer is approved for a bank loan. It requires the customer to earn > 30k per year and to have atleast 2 years of experience on his/her curren…

What is the difference here that prevents this from working?

Im reading a list of customer names and using each to find an element. Before reading the list, I make can confirm this works when I hard-code the name,datarow = driver.find_element_by_xpath("//sp…