What is the problem of the sidebar and how to fix it? - python

I'm trying to make sidebar with <Enter> and <Leave> binding and if I move my mouse slower everything works fine, but if I go faster with my mouse the sidebar starts to move back and forth without stopping. Is there a way to fix it?
(Im new with tkinter and python in general)
1/2
2/2
from tkinter import *
#MainWindow
def MainWindow():
global WindowMain
WindowMain = Tk()
WindowMain.config(background="LightGray")
WindowMain.overrideredirect(1)
#MainWindow_size
def Screen_size():
app_width = 1280
app_height = 720
screen_width = WindowMain.winfo_screenwidth()
screen_height = WindowMain.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)
WindowMain.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
#Func1
def close(e):
for x in range(1000, 1200):
Blue.place(x=x, y=0)
DarkBlue.place(x=x, y=0)
Blue.update()
DarkBlue.update()
Blue.bind("<Enter>", open)
#Func2
def open(e):
for x in range(-1200, -1000):
Blue.place(x=-x, y=0)
DarkBlue.place(x=-x, y=0)
Blue.update()
DarkBlue.update()
Blue.bind("<Leave>", close)
MainWindow()
Screen_size()
#Label1&2
Blue = Label(WindowMain, background="DeepSkyBlue",
width=70, height=50)
DarkBlue = Label(WindowMain, width=2, height=100,
background="DodgerBlue")
Blue.place(x=1200)
DarkBlue.place(x=1200)
#Buttons
Quit = Button(WindowMain, text="Quit", command=quit,
background="LightSkyBlue").pack()
Move = Button(WindowMain, text="open", command=open,
background="LightSkyBlue", state=DISABLED).pack()
Undo = Button(WindowMain, text="close", command=close,
background="LightSkyBlue", state=DISABLED).pack()
Blue.bind("<Enter>", open)
WindowMain.mainloop()

Your problem will be solved.
I just play around with Blue.update() and Blue.bind. See line
31-31 and 40-41.
In line 31-31 and 40-41, should be outside of looping.
Do not used keyword open and close. Those are valid for Python 3
Modified code:
from tkinter import *
#MainWindow
#def MainWindow():
#global WindowMain
WindowMain = Tk()
WindowMain.config(background="LightGray")
#WindowMain.overrideredirect(1)
#MainWindow_size
def Screen_size():
app_width = 1280
app_height = 720
screen_width = WindowMain.winfo_screenwidth()
screen_height = WindowMain.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)
WindowMain.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
#Func1
def _close(e):
for x in range(1000, 1200):
Blue.place(x=x, y=0)
DarkBlue.place(x=x, y=0)
Blue.update()
Blue.bind("<Enter>", _open)
#Func2
def _open(e):
for x in range(-1200, -1000):
Blue.place(x=-x, y=0)
DarkBlue.place(x=-x, y=0)
Blue.update()
Blue.bind("<Leave>", _close)
Screen_size()
#Label1&2
Blue = Label(WindowMain, background="DeepSkyBlue",
width=70, height=50)
DarkBlue = Label(WindowMain,width=2, height=100,
background="DodgerBlue")
Blue.place(x=1200)
DarkBlue.place(x=1200)
#Buttons
Quit = Button(WindowMain, text="Quit", command=quit,
background="LightSkyBlue").pack()
Move = Button(WindowMain, text="open", command=_open,
background="LightSkyBlue", state=DISABLED).pack()
Undo = Button(WindowMain, text="close", command=_close,
background="LightSkyBlue", state=DISABLED).pack()
Blue.bind("<Enter>", _open)
WindowMain.mainloop()
Screenshot before mouse moved:
Screenshot After mouse moved:

Related

Tkinter How can I withdraw and show a window?

I have successfully made a 'next' and 'back' button for the firstDicePage and secondDicePage functions so that I could return to either of the pages when needed. However, I am trying to avoid making multiple pages pop up every time I hit those buttons. I heard of .withdraw(), but I am unsure how to apply it in this code.
from tkinter import *
from tkinter import simpledialog
from tkinter import ttk
from tkinter import filedialog
from tkinter.font import Font
import tkinter as tk
import from PIL import Image, ImageTk
import tkinter
import sys
import random
def firstDicePage():
firstWindow = tkinter.Toplevel(window) # Create new window.
firstWindow.title("Dice Roller Generator")
# Change Icon photo
image = PhotoImage(file = "C:\\Users\\alexi\\Desktop\\Project Photos\\Dice logo.png")
firstWindow.iconphoto(False, image)
# Center
app_width = 900
app_height = 600
screen_width = firstWindow.winfo_screenwidth()
screen_height = firstWindow.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y= (screen_height / 2) - (app_height / 2)
firstWindow.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
Label(firstWindow, text = "\n\nSelect How Many Dice You Want to Roll!", font='Helvetica 16 bold').pack()
img = ImageTk.PhotoImage(Image.open("Dice.png"))
my_label = Label(firstWindow, image=img)
my_label.img = img # Save reference to image.
my_label.pack()
counter = tkinter.IntVar()
def increase():
counter.set(min(10, counter.get() + 1))
def decrease():
counter.set(max(0, counter.get() - 1))
lbl = Label(firstWindow, textvariable = counter, font='Helvetica 16 bold')
lbl.place(x=450, y=330)
btn1 = Button(firstWindow, text="+", font='Helvetica 16 bold', padx = 8, pady = 5, command = increase, fg="dark green", bg = "white")
btn1.place(x=499, y=320)
btn2 = Button(firstWindow, text ="-", font='Helvetica 16 bold', padx = 11.1, pady = 5, command = decrease, fg="dark green", bg = "white")
btn2.place(x=375, y=320)
btn3 = Button(firstWindow, text = "Next", font='Helvetica 16 bold', command=lambda: secondDicePage())
btn3.place(x = 800 , y = 530)
def secondDicePage():
secondWindow = tkinter.Toplevel(window) # Create new window.
secondWindow.title("Dice Roller Generator")
# Change Icon photo
image = PhotoImage(file = "C:\\Users\\alexi\\Desktop\\Project Photos\\Dice logo.png")
secondWindow.iconphoto(False, image)
# Center
app_width = 900
app_height = 600
screen_width = secondWindow.winfo_screenwidth()
screen_height = secondWindow.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y= (screen_height / 2) - (app_height / 2)
secondWindow.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
btn3 = Button(secondWindow, text = "Back", font='Helvetica 16 bold', command=lambda: firstDicePage())
btn3.place(x = 30 , y = 530)
def secondButton():
# Toplevel object which will
# be treated as a new window
secondWindow = Toplevel(window)
secondWindow.title("Dice Roller Generator")
# Change Icon photo
img = PhotoImage(file = "C:\\Users\\alexi\\Desktop\\Project Photos\\Dice logo.png")
secondWindow.iconphoto(False, img)
# Center
app_width = 600
app_height = 400
screen_width = secondWindow.winfo_screenwidth()
screen_height = secondWindow.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y= (screen_height / 2) - (app_height / 2)
secondWindow.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
# A Label widget to show in top-level
Label(secondWindow, text = "\n\nSelect What/How Many Dice You Want to Roll!", font='Helvetica 16 bold').pack()
# Create the window(root interface)
window = Tk()
# Create a title
window.title("Dice Roller Generator")
# Change Icon photo
img = PhotoImage(file = "C:\\Users\\alexi\\Desktop\\Project Photos\\Dice logo.png")
window.iconphoto(False, img)
# Center
app_width = 600
app_height = 400
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y= (screen_height / 2) - (app_height / 2)
window.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
# Create a label widget
lbl = Label(window, text = "\n\n\nChoose the Kind of Die You Want to Roll", font='Helvetica 16 bold')
#Packing(size), Shove it in the screen
lbl.pack()
btn1 = Button(window, text = "Regular Dice", padx = 15, pady = 15, command = firstDicePage)
btn1.place(x=145, y=130)
btn2 = Button(window, text = "D&D Dice", padx = 20, pady = 15, command = secondButton)
btn2.place(x=355, y=130)
btn3 = Button(window, text="Exit", padx = 15, pady = 5, command = window.quit)
btn3.place(x=275, y=335)
window.mainloop()

Displaying frames in TKinter without classes

I'm currently writing a library system and, in order to better understand how to change between frames, have so far have written code for a screen the user is met with when they first use the program as shown below:
import tkinter as tk
import json
window = tk.Tk() # creates a window
width = 474 # sets the width and height of the screen
height = 266
screen_width = window.winfo_screenwidth() # finds the width of the user's screen
screen_height = window.winfo_screenheight()
center_x = int(screen_width / 2 - width / 2)
center_y = int(screen_height / 2 - height / 2)
window.geometry(f'{width}x{height}+{center_x}+{center_y}') # sets the width, height, and positioning of the window
window.title("Library System") # sets title of window
window.resizable(False, False) # Prevents the window being resized by both the x and y coordinates
welcome = tk.Frame(width=200, height=200, background="light cyan")
ChangeInfo = tk.Frame(window, width=400, height=200)
ChangeInfo.pack(fill='both', expand=True, padx=0, pady=0)
def WelcomeScreen():
greeting = tk.Label(welcome, text="Welcome", font=("comic sans", 15), bg ='light cyan') # creates a lable with text
greeting.pack()
explaination = tk.Label(welcome, text="This is your first time using this program so please click the button below to "
"enter in \n the username "
"and password you will be using to log into the system in the future"
"", font=("comic_sans", 9), bg="light cyan")
explaination.place(x = (width)/2, y= 50, anchor='center')
login_button = tk.Button(welcome, text="Set username and password", height=3, width=22,
font=("comic_sans", 10), bg = "turquoise")
login_button.place(x= width / 2, y= height / 2, anchor='center')
window.mainloop()
WelcomeScreen()
The only thing that is displayed at the moment is the window and its title. How do I display the frame instead of only the window?
If you want to show the welcome frame initially, you need to call welcome.pack(...) instead of ChangeInfo.pack(...).

How to make a Tkinter frame raise from different files?

I'm trying to use Tkinter to create a GUI for a school planner and I want to have users be able to log in and create an account. It might get too lengthy if I try to code the entire project in one file, so I'm trying to split it up. My main file just has:
try:
import tkinter as tk # python 3
from tkinter import font as tkfont # python 3
except ImportError:
import Tkinter as tk # python 2
import tkFont as tkfont # python 2
import TkWindow
app = TkWindow.TkWindow()
app.getRoot().mainloop()
Where my TkWindow file is the file that runs everything. It looks like this:
from tkinter import *
import mainMenu
import CreateAccount
class TkWindow:
def __init__(self):
self.master = Tk() # Makes the window
self.master.wm_title("School Planner")
self.master.config(background="#FFFFFF")
# Master window dimensions
app_width = 1000
app_height = 500
screen_width = self.master.winfo_screenwidth() # Get screen width
screen_height = self.master.winfo_screenheight() # Get screen height
x = int((screen_width / 2) - (app_width / 2)) # X coordinate to center application
y = int((screen_height / 2) - (app_height / 2)) # Y coordinate to center application
self.dimensions = f'{app_width}x{app_height}+{x}+{y}'
self.master.geometry(self.dimensions) # Set master geometry
container = Frame(self.master, width=app_width, height=app_height, relief='raised', borderwidth=5)
# self.currentFrame = Frames.main(self.master)
self.frames = {}
for F in (mainMenu.MainMenu, CreateAccount.CreateAccount):
page_name = F.__name__
frame = F(master=container.master, controller=self)
self.frames[page_name] = frame
self.show_frame("MainMenu")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
def getRoot(self):
return self.master
Where my mainMenu file is:
from tkinter import *
import Fonts
import CreateAccount
class MainMenu(Frame):
def __init__(self, master, controller):
Frame.__init__(self, master)
self.root = master
self.root.title("Benjamin's School Planner")
# TODO: get an icon and find the path of it
# master.iconbitmap('HERE SHOULD GO THE FILE PATH TO THE ICON')
# Master window dimensions
app_width = 1000
app_height = 500
#screen_width = master.winfo_screenwidth() # Get screen width
#screen_height = master.winfo_screenheight() # Get screen height
#x = int((screen_width / 2) - (app_width / 2)) # X coordinate to center application
#y = int((screen_height / 2) - (app_height / 2)) # Y coordinate to center application
#master.geometry(f'{app_width}x{app_height}+{x}+{y}') # Set master geometry
# Set and display welcome message
welcome_label = Label(self.root, text='Welcome to the School Planner', font=Fonts.welcomeFont())
welcome_label.pack()
# Set and display username prompt
username_label = Label(self.root, text='Username', font=Fonts.loginFont())
username_label.place(relx=0.4, rely=0.4, anchor='center')
username_entry = Entry(self.root)
username_entry.place(relx=0.55, rely=0.4, anchor='center')
# Set and display username prompt
password_label = Label(self.root, text='Password', font=Fonts.loginFont())
password_label.place(relx=0.4, rely=0.5, anchor='center')
password_entry = Entry(self.root, show="\u2022")
password_entry.place(relx=0.55, rely=0.5, anchor='center')
# Login button command:
def login():
print("Logged in Successfully")
# Login button creation:
login_button = Button(text='Login',
command=lambda: login(),
bg='Gray', fg='Black', font=Fonts.loginFont())
login_button.place(relx=0.5, rely=0.62, anchor='center')
# 'Show Password' Checkbox creation
checkboxVar = IntVar()
def showPassword():
if checkboxVar.get() == 1:
password_entry.config(show="")
password_entry.update()
elif checkboxVar.get() == 0:
password_entry.config(show="\u2022")
show_password_checkbox = Checkbutton(master,
text="Show Password",
font=Fonts.showPasswordFont(),
variable=checkboxVar,
command=showPassword)
show_password_checkbox.place(relx=0.5, rely=0.7, anchor='center')
# Create Account button creation:
create_account_button = Button(text='Create Account',
command=lambda: controller.show_frame("CreateAccount"),
bg='Gray', fg='Black', font=Fonts.createAccountFont())
create_account_button.place(relx=0.5, rely=0.7, anchor='center')
And my CreateAccount file is:
from tkinter import *
import Fonts
class CreateAccount(Frame):
def __init__(self, master, controller):
Frame.__init__(self, master)
#master.title("Create Account")
master.config(bg='blue')
# Master window dimensions
app_width = 1000
app_height = 500
#screen_width = master.winfo_screenwidth() # Get screen width
#screen_height = master.winfo_screenheight() # Get screen height
#x = int((screen_width / 2) - (app_width / 2)) # X coordinate to center application
#y = int((screen_height / 2) - (app_height / 2)) # Y coordinate to center application
#master.geometry(f'{app_width}x{app_height}+{x}+{y}') # Set master geometry
welcome_label = Label(master, text='We made it to create account', font=Fonts.welcomeFont())
welcome_label.pack()
I'm having trouble where when it runs, it's running both frames at the same time at the beginning and I'm not sure why. Whenever I press the "create account" button, it registers that a frame should switch, but the new one doesn't arise. Does anyone know why?

Getting current value when dragging canvas

I am trying to make a simple card game, something like Solitaire.
I am not experienced in coding, so forgive me if it's a simple question.
I want to move some canvas objects. New objects have the right value, but when i am dragging an already existing card it shows the wrong value (waarde in Dutch). I would like to bind the value (waarde) to a card, but don't know how to do that...
Thought about tags, binding, ID....
from tkinter import *
from random import randint
window = Tk()
deck = [1,2,3,4,5,6]
def pakkaart():
rand_card = randint(0,len(deck)-1)
global waarde
waarde = deck[rand_card]
deck.pop(rand_card)
global kaart
kaart = Canvas(window, width = 40, height = 40, bg='yellow')
kaart.place(x=50, y=50, anchor=CENTER)
kaart.create_text(20,20,text=(waarde))
kaart.bind("<B1-Motion>", drag)
def drag(event):
event.widget.place(x=event.x_root, y=event.y_root,anchor=CENTER)
print(waarde)
button1 = Button(window, text="Nieuwe Kaart", command=pakkaart)
button1.pack()
window.mainloop()
So essentially looking for a way to bind a value to a canvas.
Your above code works fine, it shows the correct value, but if you want you can try this
from tkinter import *
from random import randint
window = Tk()
ws = window.winfo_screenwidth()
hs = window.winfo_screenheight()
w = 500 # width for the Tk root
h = 300 # height for the Tk root
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
window.geometry('%dx%d+%d+%d' % (w, h, x, y))
deck = [1, 2, 3, 4, 5, 6]
def pick_card():
global waarde, kaart
rand_card = randint(0, len(deck)-1)
card_number = deck[rand_card]
deck.remove(card_number)
card = Canvas(window, width=40, height=40, bg='yellow')
card.place(x=50, y=50, anchor=CENTER)
card_number_text = card.create_text(20, 20, text=card_number, tags=card_number)
card.bind("<Button-1>", lambda event: get_number(event, card_number_text)) # or you can use: card.bind("<Button-1>", lambda event: print(card_number))
card.bind("<B1-Motion>", drag)
def drag(event):
# This is better for move a widget
cx = window.winfo_pointerx() - window.winfo_rootx()
cy = window.winfo_pointery() - window.winfo_rooty()
event.widget.place(x=cx, y=cy)
def get_number(event, number):
print(event.widget.itemcget(number, "text"))
button1 = Button(window, text="Generate Card", command=pick_card)
button1.pack()
window.mainloop()
I've modified the drag(event) function and wrote two ways for get the current card value, for store it you can use some global varibles or create a class, the second would be better

How to insert a picture into the splash screen?

I just want to know how could I insert a picture into the splash screen?
from tkinter import *
#splash screen
class SplashScreen(Frame):
def __init__(self, master=None, width=0.8, height=0.6, useFactor=True):
Frame.__init__(self, master)
self.pack(side=TOP, fill=BOTH, expand=YES)
# get screen width and height
ws = self.master.winfo_screenwidth()
hs = self.master.winfo_screenheight()
w = (useFactor and ws * width) or width
h = (useFactor and ws * height) or height
# calculate position x, y
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
self.master.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.master.overrideredirect(True)
self.lift()
if __name__ == '__main__':
root = Tk()
sp = SplashScreen(root)
sp.config(bg="#3632ff")
m = Label(sp, text="MH60 NAVIGATION APP")
m.pack(side=TOP, expand=YES)
m.config(bg="#3366ff", justify=CENTER, font=("calibri", 29))
Button(sp, text="PRESS TO START", bg='red', command=root.destroy).pack(side=BOTTOM, fill=X)
root.mainloop()
Just add some widget with an image to your SplashScreen instance. For example, say your splash screen image was this .gif:
Then adding it to your code would look something like this (via a Button widget):
from tkinter import *
class SplashScreen(Frame):
def __init__(self, master=None, width=0.8, height=0.6, useFactor=True):
Frame.__init__(self, master)
self.pack(side=TOP, fill=BOTH, expand=YES)
# Add widget with the splash screen image on it.
self.img = PhotoImage(file='splash.gif')
btn = Button(self, image=self.img)
btn.pack(expand=YES, ipadx=10, ipady=10)
# get screen width and height
ws = self.master.winfo_screenwidth()
hs = self.master.winfo_screenheight()
w = (useFactor and ws * width) or width
h = (useFactor and ws * height) or height
# calculate position x, y
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
self.master.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.master.overrideredirect(True)
self.lift()
if __name__ == '__main__':
root = Tk()
sp = SplashScreen(root)
sp.config(bg="#3632ff")
m = Label(sp, text="MH60 NAVIGATION APP")
m.pack(side=TOP, expand=YES)
m.config(bg="#3366ff", justify=CENTER, font=("calibri", 29))
Button(sp, text="PRESS TO START", bg='red', command=root.destroy).pack(side=BOTTOM, fill=X)
root.mainloop()
This is how it looks running on my system:
Step 1:- Import Module.
Step 2:- Create splash screen.
step 3:- Set title and geometry for splash screen.
step 4:- Insert photo file name to be display.
step 5:- Create Label and Pack the Label.
# Import Module
from tkinter import *
splash = Tk()
splash.title("Welcome") # assigning title for splash screen
splash.geometry("800x750+300+100") # set geometry for splash screen
splash.after(4000, splash.destroy) # splash screen will destroy after 4 sec
bg = PhotoImage(file = "file_name.png") # insert file name to be display
lab = Label(splash, image = bg) # create label
lab.pack() # pack the label
splash.mainloop()
bg = PhotoImage(file = "file_name.png") # insert file name to be display
file_name(photo) should be present(save) in folder where above code is saved.
If file_name is not given in code or the image does not exist in folder where above code is saved then the error will appear while running code.
Error:-
_tkinter.TclError: couldn't open "file_name.png": no such file or directory
Probably you are trying to use jpg or other type of file, like jpeg..., check this or change the type of file to png.

Categories