Python Forum

Full Version: Unique Tkinter Window
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
sorry for my bad english,
i have this code
from tkinter import *

def openwindow():
    newwindow = Toplevel()
    newwindow.minsize(400,200)
    newwindow.title("new window")
    newentry = Entry(newwindow)
    newentry.pack()
    newentry.insert(END, f"edit here")

root = Tk()
root.title("root")
root.minsize(400,200)

#if you press this button: new window(s) will appear
button = Button(root, text='Create new window')
button['command'] = openwindow
button.pack()

root.mainloop()
The problem with this code is,
that every time you press the button,
it creates a new window,
But I need a unique window,
that even if you force close "newwindow" using [Alt+F4],
the "newwindow" "Entry" will not lose the data when I press the button again,

how to do that?
please help
You could store it in a variable in the main loop and then pass it back to the window
(Aug-10-2024, 10:57 PM)menator01 Wrote: [ -> ]You could store it in a variable in the main loop and then pass it back to the window
i don't get it, can you provide the code?
This is what I came up with. There are probably better ways.

import tkinter as tk

class Data:
    ''' Data class hold the string '''
    var = 'Edit Here'


class Popup:
    ''' Popup class is our window '''
    def __init__(self):
        self.window = tk.Toplevel(None)
        self.var = tk.StringVar()

        self.entry = tk.Entry(self.window, textvariable=self.var)
        self.entry.pack()
        self.entry.focus()

class Window:
    ''' Class for main view '''
    def __init__(self, parent):
        self.parent = parent
        self.button = tk.Button(parent, text='Open Window')
        self.button.pack()


class Controller:
    ''' Controller class for communications between classes '''
    def __init__(self, data, window, popup):
        self.data = data
        self.window = window
        self.popup = popup

        # Button command
        self.window.button.configure(command=self.openwindow)


    def openwindow(self):
        ''' Method for opening new window '''
        field = self.popup()
        field.entry.insert('end',self.data.var)
        field.var.trace('w', lambda var,index,mode:self.callback(field.var,0,'w'))

    def callback(self, var, index, mode):
        ''' Method for writing to Data class '''
        self.data.var = var.get()
        
if __name__ == '__main__':
    root = tk.Tk()
    controller = Controller(Data(), Window(root), Popup)
    root.mainloop()
(Aug-11-2024, 12:18 AM)menator01 Wrote: [ -> ]This is what I came up with. There are probably better ways.

import tkinter as tk

class Data:
    ''' Data class hold the string '''
    var = 'Edit Here'


class Popup:
    ''' Popup class is our window '''
    def __init__(self):
        self.window = tk.Toplevel(None)
        self.var = tk.StringVar()

        self.entry = tk.Entry(self.window, textvariable=self.var)
        self.entry.pack()
        self.entry.focus()

class Window:
    ''' Class for main view '''
    def __init__(self, parent):
        self.parent = parent
        self.button = tk.Button(parent, text='Open Window')
        self.button.pack()


class Controller:
    ''' Controller class for communications between classes '''
    def __init__(self, data, window, popup):
        self.data = data
        self.window = window
        self.popup = popup

        # Button command
        self.window.button.configure(command=self.openwindow)


    def openwindow(self):
        ''' Method for opening new window '''
        field = self.popup()
        field.entry.insert('end',self.data.var)
        field.var.trace('w', lambda var,index,mode:self.callback(field.var,0,'w'))

    def callback(self, var, index, mode):
        ''' Method for writing to Data class '''
        self.data.var = var.get()
        
if __name__ == '__main__':
    root = tk.Tk()
    controller = Controller(Data(), Window(root), Popup)
    root.mainloop()
Thank you for the reply and the code,
your code is work, the data still there,
but it still creates multiple windows when you press the button,
is there a way to check if the windows exist in the first place?
I altered the code a little. I disabled the button if the popup is open. When the popup is closed, the button will enable again.
You could also use withdraw and deiconify if wanted
import tkinter as tk

class Data:
    ''' Data class hold the string '''

    # Default text for the class variable
    var = 'Edit Here'


class Popup:
    ''' Popup class is our window '''
    def __init__(self):
        # Set class instance variables and create the popup window
        self.window = tk.Toplevel(None)
        self.window.geometry('400x200+300+300')
        self.window.configure(pady=20, padx=10)

        # Create a class variable for the entry field
        self.var = tk.StringVar()

        # Create the entry field and set focus
        self.entry = tk.Entry(self.window, textvariable=self.var)
        self.entry.pack(fill='x')
        self.entry.focus()

class Window:
    ''' Class for main view '''
    def __init__(self, parent):
        # Setting some class variables and creating the main window
        # with a button
        self.parent = parent
        self.parent.geometry('200x200')
        self.parent.configure(pady=20)
        self.button = tk.Button(parent, text='Open Window')
        self.button.pack()


class Controller:
    ''' Controller class for communications between classes '''
    def __init__(self, data, window, popup):

        # Set class instance variables
        self.data = data
        self.window = window
        self.popup = popup

        # Set a button command for the main window button
        self.window.button.configure(command=self.openwindow, cursor= 'hand2')
        

    def openwindow(self):
        ''' Method for opening new window '''

        # Create and open popup window by calling the Popup class
        self.field = self.popup()

        # Insert the data class variable text
        self.field.entry.insert('end',self.data.var)

        # Keep track of what's beeing typed in the entry field
        self.field.var.trace('w', lambda var,index,mode:self.callback(self.field.var))

        # Disable the window button when popup is open
        self.window.button.configure(state='disabled', cursor='pirate')

        # If you want to use withdraw, uncomment the below line
        # self.window.parent.withdraw()

        # When the popup window is closed call function to enable the button
        self.field.window.protocol('WM_DELETE_WINDOW', self.enable)

    def callback(self, var, index=None, mode=None):
        ''' Method for writing to Data class variable '''
        self.data.var = var.get()

    def enable(self):
        ''' Method for enabling button and destroying popup window '''

        # Destroy popup window
        self.field.window.destroy()

        # Enable button
        self.window.button.configure(state='normal', cursor='hand2')

        # If using withdraw uncomment below line
        # self.window.parent.deiconify()
       
        
if __name__ == '__main__':
    root = tk.Tk()
    controller = Controller(Data(), Window(root), Popup)
    root.mainloop()
(Aug-11-2024, 01:35 AM)menator01 Wrote: [ -> ]I altered the code a little. I disabled the button if the popup is open. When the popup is closed, the button will enable again.
You could also use withdraw and deiconify if wanted
import tkinter as tk

class Data:
    ''' Data class hold the string '''
    var = 'Edit Here'


class Popup:
    ''' Popup class is our window '''
    def __init__(self):
        self.window = tk.Toplevel(None)
        self.window.geometry('400x200+300+300')
        self.window.configure(pady=20, padx=10)
        self.var = tk.StringVar()

        self.entry = tk.Entry(self.window, textvariable=self.var)
        self.entry.pack(fill='x')
        self.entry.focus()

class Window:
    ''' Class for main view '''
    def __init__(self, parent):
        self.parent = parent
        self.parent.geometry('200x200')
        self.parent.configure(pady=20)
        self.button = tk.Button(parent, text='Open Window')
        self.button.pack()


class Controller:
    ''' Controller class for communications between classes '''
    def __init__(self, data, window, popup):
        self.data = data
        self.window = window
        self.popup = popup

        # Button command
        self.window.button.configure(command=self.openwindow, cursor= 'hand2')
        

    def openwindow(self):
        ''' Method for opening new window '''
        self.field = self.popup()
        self.field.entry.insert('end',self.data.var)

        self.field.var.trace('w', lambda var,index,mode:self.callback(self.field.var))
        self.window.button.configure(state='disabled', cursor='pirate')
        # self.window.parent.withdraw()

        self.field.window.protocol('WM_DELETE_WINDOW', self.enable)

    def callback(self, var, index=None, mode=None):
        ''' Method for writing to Data class '''
        self.data.var = var.get()

    def enable(self):
        self.field.window.destroy()
        self.window.button.configure(state='normal', cursor='hand2')
        # self.window.parent.deiconify()
       
        
if __name__ == '__main__':
    root = tk.Tk()
    controller = Controller(Data(), Window(root), Popup)
    root.mainloop()
your code is flawless,
but i don't understand how it work,
i give you a reputation point
What part you not understand and will try to explain?
(Aug-11-2024, 03:33 AM)menator01 Wrote: [ -> ]What part you not understand and will try to explain?
sorry it very basic, i don't understand class,
i learn java decade ago but never use it again since then,

the parts that confuse me is this
''' Controller class for communications between classes '''
how those thing communicated,
can it work without make it class?
I'm sure it can. I haven't done any procedural programming in a long time. I found that it's usually easier to use classes (for me anyway) All the controller class does is (in this case) get data from the popup window and store it in the data class and pulls the variable from the data class and inserts into the entry in the popup window. It also enables and disables the button in the window class while the popup window is opened or closed.
Pages: 1 2