python(OOPS) tkinter button not appearing - python

i am trying to make a library management system in python using oops and tkinter.
here is the code:
from tkinter import *
class library():
def __init__(self):
self.screen=Tk()
self.title='LOGIN'
self.screen.minsize(800,600)
self.screen.maxsize(800,600)
self.screen.title(self.title)
c=Canvas(self.screen,bg='black').place(x=-10,y=0,height=1000,width=1000)
def screen_work(self):
self.screen_login().screen.destroy()
screen=Tk()
screen.title('LIBRARY MANAGEMENT')
#screen.attributes('-fullscreen',True)
def button(self):
Button(self.screen,text='press',bg='red').place(x=400,y=300)
lib=library()
mainloop()
now ,when i run this program a black screen of dimension '800x600; opens up without any errors but does not show any button.

As Bryan Oakley and JRiggles rightly stated, the button function is never called, so it wouldn't display
updated code
from tkinter import *
class library():
def __init__(self):
self.screen=Tk()
self.title='LOGIN'
self.screen.minsize(800,600)
self.screen.maxsize(800,600)
self.screen.title(self.title)
c=Canvas(self.screen,bg='black').place(x=-10,y=0,height=1000,width=1000)
def screen_work(self):
self.screen_login().screen.destroy()
screen=Tk()
screen.title('LIBRARY MANAGEMENT')
#screen.attributes('-fullscreen',True)
def button(self):
Button(self.screen,text='press',bg='red').place(x=400,y=300)
lib=library()
lib.button()
mainloop()
here's a great resource to learn tkinter in case you're interested!
https://realpython.com/python-gui-tkinter/

You don’t really need to use a function to add a button, you may just leave the button code near the end after the other functions. If you want to keep the function, I think you forgot to declare the function in order for the button to appear.

Related

Moving TKinter Window.destroy to a function from a button, not so simple?

I'm giving myself a crash-course in Python and TKinter, but there is one small detail I can't grasp.
Closing a Toplevel window in a function instead of a button.
My button alone works perfect:
button = Button(UpdateWindow, text="Destroy Window", command=UpdateWindow.destroy)
Using a button with a reference to a close function bombs:
def Close():
tkMessageBox.showwarning('', 'Close function called', icon="warning")
command=UpdateWindow.destroy
btn_updatecon = Button(ContactForm, text="Update", width=20, command=lambda:[UpdateData(), Close()])
What am I missing in the function? It is being called, but no close.
The SQLite3 project im working with is here
Any guidance greatly appreciated.
command=UpdateWindow.destroy defines a variable. If you want to keep the command variable use command(), while if you want the recommended way use UpdateWindow.destroy()

How do I destroy a Tk window after opening another with a function?

I am trying to open a whole new file with a different GUI after the user presses the Login button, but I cant seem to destroy the main Tk window when they click it.
def __init__(self, master=None): #This is how I initialized the TK window
tkinter.Tk.__init__(self,master)
m_login = tkinter.Button(text="Login",bg="#1e1e1e",foreground="#b4b4b4",width=10,command=self.login)
def login(self):
os.startfile('maingui.py')
self.tkinter.destroy() #Idk what goes here
self.destroy
works in most cases, but I found that importing the class and function then closing the first one seemed to work best.

Python Tkinter how to hide a widget without removing it

I know similar things have been asked a lot, but I've tried to figure this out for two hours now and I'm not getting anywhere. I want to have a button in a Tkinter window that is only visible on mouseover. So far I failed at making the button invisible in the first place (I'm familiar with events and stuff, that's not what this question is about) pack_forget() won't work, because I want the widget to stay in place. I'd like some way to do it like I indicated in the code below:
import tkinter as tki
class MyApp(object):
def __init__(self, root_win):
self.root_win = root_win
self.create_widgets()
def create_widgets(self):
self.frame1 = tki.Frame(self.root_win)
self.frame1.pack()
self.btn1 = tki.Button(self.frame1, text='I\'m a button')
self.btn1.pack()
self.btn1.visible=False #This doesnt't work
def main():
root_win = tki.Tk()
my_app = MyApp(root_win)
root_win.mainloop()
if __name__ == '__main__':
main()
Is there any way to set the visibility of widgets directly? If not, what other options are there?
Use grid as geometry manager and use:
self.btn1.grid_remove()
which will remember its place.
You can try using event to call function.
If "Enter" occurs for button then call a function that calls pack()
and if "Leave" occurs for button then call a function that calls pack_forget().
Check this link for event description:List of All Tkinter Events
If you wish your button to stay at a defined place then you can use place(x,y) instead of pack()

Python: How to use a tkinter Checkbutton in OOP functions

I have got stuck with this particular bit of code. I have condensed down the problem to this section.
I am running a sort of menu in Python, where the first menu sends you to the second menu, and in the second menu, there is a checkbutton the user can toggle on/off. In the third menu, I want it to read if the checkbutton is on/off and convert it to a Boolean. Code:
import tkinter as tk
class MainMenu(object):
def __init__(self):
self.launch_MainMenu()
def launch_MainMenu(self):
self.master = tk.Tk()
tk.Button(self.master,text="MY BUTTON",command= lambda:self.launch_SideMenu()).grid()
tk.mainloop()
def launch_SideMenu(self):
self.master2 = tk.Tk()
self.var1 = tk.IntVar()
tk.Checkbutton(self.master2,variable=self.var1).grid()
tk.Button(self.master2,text="Test",command= lambda:self.launch_FinalMenu()).grid()
def launch_FinalMenu(self):
d = bool(int(self.var1.get()))
print(d,self.var1.get())
mainMenu = MainMenu()
Output: Whether the checkbox is on or off, it outputs "False 0".
Any help would be very much appreciated!
As per the hint from Lafexlos, the error is in calling tk.Tk() twice. For a new window, you must use tk.Toplevel().
Simply changing the keyline to:
self.master2 = tk.Toplevel()
fixes everything. This took me a long time to work out. Thanks for the help, and best of luck to you coders reading this in the future.

Tkinter: Window flash when attempting to click away

Ive been trying to do this for a while now, but haven't figured out a way to do it.
I have a tkinter script, that creates a popup window when a button is pressed. However I don't want the user to be able to click away from this window to any previous windows created. I have got this working with root.grab_set(), however there is no indication to the user that they must stay on that window.
class popup(object):
def __init__(self, parent):
self.root=Toplevel(parent)
self.root.grab_set() #prevents the user clicking on the parent window
#But the window doesnt 'flash' when an attempt to click away is made
For example, when you have a window created by the filedialogue module, if you attempt to click onto another window the filedialogue window stays on top and has a 'flashing' animation to let the user know they cant click away. Is there a way I can reproduce this effect? Going through the source of filedialogue hasn't been fruitful for me, and neither have Google searches.
The simplest way i can think to do this is to use an event and the focus commands, along with the windows bell command:
#!python3
import tkinter as tk
class popup(object):
def __init__(self, parent):
self.root=tk.Toplevel(parent)
self.root.title("Popup")
self.root.bind("<FocusOut>", self.Alarm)
def Alarm(self, event):
self.root.focus_force()
self.root.bell()
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
Here's a solution for Windows that uses FlashWindowEx from the user32 dll. You need to pass a FLASHWINFO object to it. The grab_set makes sure the popup window stays in focus and disables any widgets in the main window, making the popup transient makes sure it's always on top of the master. The <Button-1> event is used to check mouse clicks, and winfo_containing checks if another window than the popup is clicked. I then set the focus back to the popup and flash the window in focus (which then always is the popup).
You need pywin32 to use this.
import Tkinter as tk
from ctypes import *
import win32con
class popup(object):
def __init__(self, parent):
self.parent = parent
self.root=tk.Toplevel(self.parent)
self.root.title("Popup")
self.root.grab_set()
self.root.transient(self.parent)
self.root.bind("<Button-1>", self.flash)
def flash(self, event):
if self.root.winfo_containing(event.x_root, event.y_root)!=self.root:
self.root.focus_set()
number_of_flashes = 5
flash_time = 80
info = FLASHWINFO(0,
windll.user32.GetForegroundWindow(),
win32con.FLASHW_ALL,
number_of_flashes,
flash_time)
info.cbSize = sizeof(info)
windll.user32.FlashWindowEx(byref(info))
class FLASHWINFO(Structure):
_fields_ = [('cbSize', c_uint),
('hwnd', c_uint),
('dwFlags', c_uint),
('uCount', c_uint),
('dwTimeout', c_uint)]
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
As it is now, the flash only occurs when the main window's body is clicked, so clicking the title bar just returns the focus to the popup without flashing. To make it fire also when that happens you could try using the <FocusOut> event, but you would have to make sure it only happens when the focus passes to the main window, but it never really does since the grab_set is used. You might want to figure that out, but as it is now it works quite well. So it's not perfect, but I hope it helps.

Categories