Why the quit button is not shown - python

I am trying the following code about python:
import tkinter
from tkinter import *
from tkinter.messagebox import askokcancel
class Quitter(Frame):
def _init__(self,parent=None):
Frame.__init__(self,parent)
self.pack()
widget=Button(self,text='Quit',command=self.quit)
widget.pack(side=TOP,expand=YES,fill=BOTH)
def quit(self):
ans=askokcancel('Verify exit',"You want to quit?")
if ans:Frame.quit(self)
if __name__=='__main__':Quitter().mainloop()
When executing it, I get a frame like this:
But where is the Quit button?

As mentioned in the comments, you have a typo in __init__().
Further, you probably want to structure your app as follows: (1) not importing tkinter in the main namespace, (2) keep track of the root/parent in the tk.Frame class, and use root.destroy() i/o quit()
import tkinter as tk
from tkinter.messagebox import askokcancel
class Quitter(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
self.widget = tk.Button(self.parent, text='Quit', command=self.quit)
self.widget.pack()
def quit(self):
ans = askokcancel('Verify exit', "You want to quit?")
if ans:
self.parent.destroy()
if __name__ == "__main__":
root = tk.Tk()
Quitter(root)
root.mainloop()
You will find more info in this thread.

Related

How to create a subclass of ttk.Button correctly (class function doesnt work)?

I want to create Buttons with a text and define a function that prints me the text on the monitor when i press the button.
Everything works well without classes:
from tkinter import *
from tkinter import ttk
def PressButton():
print(FirstButton.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=ttk.Button(ButtonsFrame, text=1, command= PressButton)
FirstButton.grid()
root.mainloop()
"1" is printed on the monitor when I press FirstButton.
Because I want to have a lot of Buttons, I created a class MyButton with the parent ttk.Button:
from tkinter import *
from tkinter import ttk
class MyButton(ttk.Button):
def __init__(self, text):
self.text=text
super().__init__()
self.Button=ttk.Button(ButtonsFrame, text=self.text, command=self.PressButton)
def PressButton(self):
print(self.Button.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(1)
FirstButton.grid()
root.mainloop()
Here a button is created but without text at all.
I found out that if I change the super().__init__() to super()._init__(text=self.text) then I get a Button with the right text but the PressButton command doesnt work. I tried diffent things with *args aswell but had no success.
What am I doing wrong? I would appreciate any help.
The main problem is that you're not specifying the parent widget for the parent in the constructor.
Here's corrected version of code:
from tkinter import *
from tkinter import ttk
class MyButton(ttk.Button):
def __init__(self, parent, text):
self.text=text
super().__init__(parent, text=self.text, command=self.PressButton)
def PressButton(self):
print(self.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(ButtonsFrame, 1)
FirstButton.grid()
root.mainloop()
You could've also swapped super(). with this:
super(MyButton,self).__init__(parent, text=self.text,command=self.PressButton)
Which is equal to super().__init__(parent, text=self.text, command=self.PressButton)
You can read more about it here:
https://docs.python.org/3/library/functions.html#super

Python Tkimport how to make one from several windows when importing from a module?

I am writing an application in tkinter consisting of several modules in which there are classes. Each module to a separate page of the app. As I move the buttons between the pages "next", "previous" it opens a new window for me every time. How do I make it so that each time calling pages opens in the same window?
I give draft code.
thank you for your help :D
task1.py
import tkinter as tk
from Test.modul.task1 import FirstPage1
class FirstPage0:
def __init__(self, root):
self.root = root
def get_settings(self):
# Window settings
self.root.geometry("100x200")
def get_second_page(self):
FirstPage1(tk.Toplevel()).get_run_first_page()
def get_button(self):
# Add buttons
tk.Button(self.root, text="Start page", command=self.get_second_page).pack()
tk.Button(self.root, text="Exit", command=self.root.destroy).pack()
def get_run_first_page(self):
# Launching the application
self.get_settings()
self.get_button()
self.root.mainloop()
if __name__ == '__main__':
first = FirstPage0(tk.Tk())
first.get_run_first_page()
task2.py
import tkinter as tk
class FirstPage1:
def __init__(self, root):
self.root = root
def get_settings(self):
# Window settings
self.root.geometry("100x200")
def get_second_page1(self):
from Test.task import FirstPage0
FirstPage0(tk.Toplevel()).get_run_first_page()
def get_button(self):
# Add buttons
tk.Button(self.root, text="Back", command=self.get_second_page1).pack()
tk.Button(self.root, text="Exit", command=self.root.destroy).pack()
def get_run_first_page(self):
# Launching the application
self.get_settings()
self.get_button()
self.root.mainloop()
if __name__ == '__main__':
first = FirstPage1(tk.Tk())
first.get_run_first_page()
Solution
#AdrianSz, you wanted to make the buttons not stack under each other. There are three ways to do so. One, is to keep only one button and change its command and text parameters each time when the frames change. Another would be to unpack the button not needed and pack the button needed. The third would be to pack the buttons in the root window instead of frame and change the text and command parameters. I would recommend the second method as it is easier and less prone to errors.
Code
task1.py
import tkinter as tk
from Test.modul.task1 import FirstPage1
class FirstPage0:
def __init__(self, root):
self.root = root
def get_settings(self):
# Window settings
self.root.geometry("100x200")
def get_second_page(self):
self.root.pg_0_btn_start.pack_forget()
self.root_pg_0_btn_exit.pack_forget()
FirstPage1(tk.Toplevel()).get_run_first_page()
def get_button(self):
# Add buttons
self.root.pg_0_btn_start = tk.Button(self.root, text="Start page",
command=self.get_second_page).pack()
self.root_pg_0_btn_exit = tk.Button(self.root, text="Exit",
command=self.root.destroy).pack()
def get_run_first_page(self):
# Launching the application
self.get_settings()
self.get_button()
self.root.mainloop()
if __name__ == '__main__':
first = FirstPage0(tk.Tk())
first.get_run_first_page()
task2.py
import tkinter as tk
class FirstPage1:
def __init__(self, root):
self.root = root
def get_settings(self):
# Window settings
self.root.geometry("100x200")
def get_second_page1(self):
from Test.task import FirstPage0
self.root.pg_1_btn_back.pack_forget()
self.root_pg_1_btn_exit.pack_forget()
FirstPage0(tk.Toplevel()).get_run_first_page()
def get_button(self):
# Add buttons
self.root.pg_1_btn_back = tk.Button(self.root, text="Back", command=self.get_second_page1).pack()
self.root.pg_1_btn_exit = tk.Button(self.root, text="Exit", command=self.root.destroy).pack()
def get_run_first_page(self):
# Launching the application
self.get_settings()
self.get_button()
self.root.mainloop()
if __name__ == '__main__':
first = FirstPage1(tk.Tk())
first.get_run_first_page()
Note: I couldn't test this code from my side so if there are any errors, please comment on this answer
Suggestions
Since you are using modules for these, just make them inherit a class specified in a different file and operate them both from that file. There you can use self to access the methods of a subclass because the subclasses instantiate the base class and thus the self is a object of the subclass and is passed to the base class. The type of code you used is quite confusing too. I have added code to give you your wanted output using the principles I mentioned here. Hope this helped!

What is the difference between self and not self objects particularly in Tkinter class?

I have this simple code with self.btn1
from tkinter import Tk, ttk, messagebox
import tkinter as tk
class Main(tk.Frame):
def __init__(self, root):
super().__init__(root)
self.btn1 = ttk.Button(self, text="test")
self.btn1.pack()
if __name__ == "__main__":
root = tk.Tk()
app = Main(root)
app.pack()
root.mainloop()
and this code without self button
from tkinter import Tk, ttk, messagebox
import tkinter as tk
class Main(tk.Frame):
def __init__(self, root):
super().__init__(root)
btn1 = ttk.Button(self, text="test")
btn1.pack()
if __name__ == "__main__":
root = tk.Tk()
app = Main(root)
app.pack()
root.mainloop()
Both of them work similarly, but what's the difference, which one should I use?
The only real difference lies in how easy it is to retrieve the reference to the Button instance should you need one. With the former, it's just app.btn1. With the latter, it's app.winfo_children()[0].
>>> app.winfo_children()[0] is app.btn1
True
The difference is that btn1 is a local variable that is only available in the function in which it is used. self.btn1 is an instance variable that is available in every function within the class.

Python program gives no error or warning but neither doeas any window appear

from tkinter import*
import tkinter.messagebox
from tkinter import ttk
import random
import time
import datetime
def main():
root = Tk()
app = Login(root)
class Login:
def __init__(self, master):
self.master = master
self.master.title("Billing Login System")
self.master.geometry("1350x750+0+0")
self.master.config(bg = 'cadet blue')
self.frame = Frame(self.master,bg='cadet blue')
self.frame.pack()
#Some code here
..(Login Conditions)
..
#
#After authentication this window should pop up
class customer:
def __init__(self, root):
self.root = root
self.root.title("eZ Billing System")
self.root.geometry("1350x750+0+0")
self.root.config(bg="cadet blue")
self.frame = Frame(self.root,bg='cadet blue')
self.frame.pack()
#some code here
if __name__ == '__main__':
main()
This code works but the problem is that when i run the file no error shows up or warnings and neither does any window shows but if i run any other python program then this windows pops up and no problems.
I am new to this and cant figure out whats wrong.
I guess you aren't creating main window instance.
That's why it is not showing error but not showing any output even.
Try adding this :
root.mainloop()

How do I create different Tkinter frames across multiple files?

I am creating a GUI on Tkinter that needs to open or close windows when buttons are pressed, and I would prefer if each window was in its own file. I tried creating a very simple example of this with the three files below. The first window is supposed to have a button that, when pressed, closes the current window and opens the next one. I'm currently running into a problem where the window is created but the button is not. How do I fix this?
Main.py
from MyTkWindow import *
myWindow = MyTkWindow()
myWindow.start()
MyTkWindow.py
import tkinter as tk
from NextFrame import *
class MyTkWindow(tk.Frame):
def __init__(self, parent=None):
tk.Frame.__init__(self)
nextWin = NextWindow()
NextScreen = tk.Button(self, text="Next", command=lambda:[self.destroy(), nextWin.start()])
NextScreen.pack()
def start(self):
self.mainloop()
NextFrame.py
import tkinter as tk
class NextWindow(tk.Frame):
def __init__(self, parent=None):
tk.Frame.__init__(self)
Leave = tk.Button(self, text="Quit", command=lambda: self.destroy())
Leave.pack()
def start(self):
self.mainloop()
I got this to work with the indicated changes. The primary problem was due to not calling the pack() method of the windows/frames being created.
main.py:
from MyTkWindow import *
myWindow = MyTkWindow()
myWindow.pack() # ADDED
myWindow.start()
MyTkWindow.py:
import tkinter as tk
from NextFrame import *
class MyTkWindow(tk.Frame):
def __init__(self, parent=None):
tk.Frame.__init__(self, parent) # ADDED parent argument.
nextWin = NextWindow()
NextScreen = tk.Button(self, text="Next",
command=lambda: [self.destroy(),
nextWin.pack(), # ADDED
nextWin.start()])
NextScreen.pack()
def start(self):
self.mainloop()
NextFrame.py:
import tkinter as tk
class NextWindow(tk.Frame):
def __init__(self, parent=None):
tk.Frame.__init__(self, parent) # ADDED parent argument.
Leave = tk.Button(self, text="Quit",
command=lambda: self.destroy())
Leave.pack()
def start(self):
self.mainloop()
Suggestion: Read and start following the PEP 8 - Style Guide for Python Code because it will make your code more understanable and maintainable. Specifically, the Naming Conventions section especially with respect to class, variable, and module file names.

Categories

Resources