2

Good evening,

I would like to build a tkinter interface with several buttons leading to differents script. Those script are functions in another folder.

In the example I built to explain my problem, the main script is test.py in the working folder and it calls the Test.py file in the BFoctions subfolder.

the test.py:

from BFonctions.Test import Affich
import tkinter as tk
from tkinter import *
from tkinter import ttk, messagebox

MaiN= tk.Tk()
MaiN.geometry('200x100')  
btn = Button(MaiN, text="Créer une nouvelle fenêtre", command = Affich)
btn.pack(pady = 10) 
MaiN.mainloop()

just create a button that calls the Affich function in the BFonctions/Test.py

the function:

import tkinter as tk
from tkinter import *
from tkinter import ttk, messagebox

def Affich():
    root = tk.Tk()
    root.title("Liste chèvres")
    root.geometry("950x900")


    text_var = tk.StringVar()

    text_var.set("test")

    label = tk.Label(root,textvariable=text_var,font=("Arial", 16, "bold"),fg="black",wraplength=500,height=3, bg='lightblue' )

    label.grid(row = 0, column = 0, sticky = W)


    Filterbutton1 = IntVar()

    FilterButton1 = Checkbutton(root, text = "test",variable = 
    Filterbutton1,onvalue = 1,offvalue = 0,height = 2, width = 10)

    FilterButton1.grid(row = 1, column = 0, sticky = W)

    root.mainloop

create a label and a checkbox.

the checkbox is fonctionning correctly, however the label is not display

I obtained a similar result with a tk.Toplevel widget exept there is an additional and unnecessary window displayed.

Is there some change in my code that would allow to obtain the desired behavior?

thank you per advance

1
  • 1
    Please edit your question to fix the indentation of your Affich code. Also you should use tk.Toplevel() to create a new window rather than creating a new tk.Tk() instance. As-written, this is essentially creating two totally separate tkinter applications. Commented Oct 23 at 12:52

1 Answer 1

2

You should use tk.Toplevel() to create new child windows rather than instantiating tk.Tk() a second time.

Your Affich function is better written as a class, which can inherit from tk.Toplevel like so:

# BFonctions.Test script
import tkinter as tk


class Affich(tk.Toplevel):  # inheritance gives this class the functions of a tk.Toplevel widget
    def __init__(self, parent: tk.Misc):  # 'self' refers to *this* class, Affich
        super().__init__(parent)  # initialize the Toplevel widget
        self.title("Liste chèvres")
        self.geometry("950x900")

        text_var = tk.StringVar(self)
        text_var.set("test")
        label = tk.Label(
            self,  # this label is a child of Affich
            textvariable=text_var,
            font=("Arial", 16, "bold"),
            fg="black",
            wraplength=500,
            height=3,
            bg='lightblue',
        )
        label.grid(row=0, column=0, sticky=tk.W)

        Filterbutton1 = tk.IntVar(self)
        FilterButton1 = tk.Checkbutton(
            self,  # this checkbutton is a child of Affich
            text="test",
            variable= Filterbutton1,
            onvalue=1,
            offvalue=0,
            height=2,
            width=10,
        )
        FilterButton1.grid(row=1, column=0, sticky=tk.W)

Then in your main script, you can instantiate it like any other tkinter widget, including creating the new window with a button press

# main script
import tkinter as tk


MaiN = tk.Tk()
MaiN.geometry('200x100')

btn = tk.Button(
    MaiN,
    text="Créer une nouvelle fenêtre",
    # the lambda here lets us specify the parent of the Affich window
    command=lambda parent=MaiN: Affich(parent)
)
btn.pack(pady=10)

MaiN.mainloop()

A few closing notes:

  • you generally want to avoid star imports, i.e. from tkinter import * as these can lead to issues like namespace pollution
  • you don't need both import tkinter as tk and from tkinter import *; generally you should just use import tkinter as tk and then prefix your widgets with tk. e.g. tk.Label, tk.Frame, etc.
  • capitalized names (like Affich) are usually reserved for classes in Python, not functions!
  • mixed-case names (like MaiN) should be avoided! Use main instead

Take a moment to familiarize yourself with the Python style guide; following style conventions helps you write code that is easier for others to understand and debug!

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your comments, I will have a look to the style guide,
Glad I could help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.