Drag Drop List in Tkinter - python-3.x

from tkinter import *
import tkinter as tk
root = tk.Tk()
def add_many_songs():
# Loop thru to fill list box
for song in range(11):
playlist_box.insert(END, song)
playlist_box =tk.Listbox(root,bg="black", fg="green", width=60, selectbackground="green", selectforeground='black',font = 20)
playlist_box.grid(row=0, column=0)
add_many_songs()
class DragDropListbox(tk.Listbox):
""" A Tkinter listbox with drag'n'drop reordering of entries. """
def __init__(self, master, **kw):
kw['selectmode'] = tk.SINGLE
tk.Listbox.__init__(self, master, kw)
self.bind('<Button-1>', self.setCurrent)
self.bind('<B1-Motion>', self.shiftSelection)
self.curIndex = None
def setCurrent(self, event):
self.curIndex = self.nearest(event.y)
def shiftSelection(self, event):
i = self.nearest(event.y)
if i < self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i+1, x)
self.curIndex = i
elif i > self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i-1, x)
self.curIndex = i
##I found this code that does drag and drop features within tkinter list. I got it to work with the example code. However, I am not able to get it to work within the attached code. I am still learning Python.

You should use the class DragDropListbox instead of tk.Listbox when creating playlist_box:
import tkinter as tk
def add_many_songs():
# Loop thru to fill list box
for song in range(11):
playlist_box.insert(tk.END, song)
class DragDropListbox(tk.Listbox):
""" A Tkinter listbox with drag'n'drop reordering of entries. """
def __init__(self, master, **kw):
kw['selectmode'] = tk.SINGLE
tk.Listbox.__init__(self, master, kw)
self.bind('<Button-1>', self.setCurrent)
self.bind('<B1-Motion>', self.shiftSelection)
self.curIndex = None
def setCurrent(self, event):
self.curIndex = self.nearest(event.y)
def shiftSelection(self, event):
i = self.nearest(event.y)
if i < self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i+1, x)
self.curIndex = i
elif i > self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i-1, x)
self.curIndex = i
root = tk.Tk()
playlist_box = DragDropListbox(root,bg="black", fg="green", width=60, selectbackground="green", selectforeground='black',font = 20)
playlist_box.grid(row=0, column=0)
add_many_songs()
root.mainloop()
Note that it is not recommended to import tkinter like below:
from tkinter import *
import tkinter as tk
Just use import tkinter as tk.

Related

Python - How to switch frames in a Tkinter window

I want to switch frames in a Tkinter window but the previous frame always stays visible in the background.
This is the code I have:
from tkinter import *
class frame(Frame):
def __init__(self,display):
Frame.__init__(self,display)
l = Label(self,text="frame1")
l.pack()
class frame2(Frame):
def __init__(self,display):
Frame.__init__(self,display)
l = Label(self,text="frame2")
l.pack()
class test(Tk):
def __init__(self):
Tk.__init__(self)
f = frame(self)
f.grid(row=0)
f2 = frame2(self)
f2.grid(row=0)
f.tkraise()
t = test()
t.mainloop()
This works if the layout of the two frames is the same but if I add another label to the second frame, it will still be visible in the Background. Is there a way to switch frames so that only elements from the raised frame are visible?
As requested, this is what I used to fix my problem:
from tkinter import *
class frame(Frame):
def __init__(self,display):
Frame.__init__(self,display)
l = Label(self,text="frame1")
l.pack()
class frame2(Frame):
def __init__(self,display):
Frame.__init__(self,display)
l = Label(self,text="frame2")
l.pack()
class test(Tk):
def __init__(self):
Tk.__init__(self)
f2 = frame2(self)
f2.grid(row=0)
#To raise the first frame, I used the following
frame2.grid_remove()
f = frame(self)
f.grid(row=0)
t = test()
t.mainloop()

Tkinter Label and Entry

I plan a mathematical game. I want the randint from label 1 + randint from label 2 to be calculated and then check if my entry is the same as the calculated number.
I want to add z1 to z2 and check if the Entry is the same but I don't know how I can add one random number to the other.
I can't add z1 to z2 so what is the way to do that? Should this happen in the if...else?
from tkinter import *
from random import *
fenster = Tk()
fenster.title("Mathe-Spiel")
fenster.geometry("300x300")
def anfang():
z1 =label = Label(fenster, text=(randint(1,100)))
label.pack()
zp=label2 = Label(fenster, text="+")
label2.pack()
z2= label1 = Label(fenster, text=(randint(1,100)))
label1.pack()
a =label3 = Label(fenster,)
label3.pack()
e1=eingabe = Entry(fenster)
eingabe.pack()
e2=z1+z2
def ausgabe():
if (e1==e2):
a.configure(text=(eingabe.get()))
else:
a.configure(text="Falsch")
ergebnis = Button(fenster, text="ergebnis", command= ausgabe)
ergebnis.pack()
anfangsknopf = Button(fenster, text="Fange mit dem Spielen an", command=anfang)
anfangsknopf.pack()
mainloop()
Error: You are trying adding 2 labels together (e2=z1+z2) but you expect that you add the values in your z1 and z2 text option!
You can get the right values while get text from z1 and z2 but I would do it in a different way.
like so:
from tkinter import Tk, IntVar, Button, Label, Entry
from random import randint
class Gui:
def __init__(self, master):
self.master = master
self.summand1 = IntVar()
self.summand2 = IntVar()
anfangsknopf = Button(self.master, text="Fange mit dem Spielen an", command=self.create_widgets)
anfangsknopf.pack()
def create_widgets(self):
""" create widgets on the fly """
try:
self.label1.destroy()
self.label2.destroy()
self.label3.destroy()
self.eingabe.destroy()
self.ergebnis.destroy()
self.answer.destroy()
except:
print("No widgets destroyed")
self.fill_summands()
self.label1 = Label(self.master, textvariable=self.summand1)
self.label2 = Label(self.master, text="+")
self.label3 = Label(self.master, textvariable=self.summand2)
self.eingabe = Entry(self.master)
self.ergebnis = Button(self.master, text="ergebnis", command= self.ausgabe)
self.answer = Label(self.master, text="...")
self.label1.pack()
self.label2.pack()
self.label3.pack()
self.eingabe.pack()
self.ergebnis.pack()
self.answer.pack()
self.eingabe.focus_set()
def get_random_nr(self):
""" get random number """
return randint(1,100)
def fill_summands(self):
""" set IntVar variables """
r_number1 = self.get_random_nr()
r_number2 = self.get_random_nr()
self.summand1.set(r_number1)
self.summand2.set(r_number2)
def ausgabe(self):
""" calculate addition """
try:
if self.summand1.get()+self.summand2.get() == int(self.eingabe.get()):
print("Correct")
self.answer.configure(text="Correct", fg="Green")
else:
print("Wrong")
self.answer.configure(text="Wrong", fg="Red")
except ValueError:
print("Please set a number in Entry widget")
self.answer.configure(text="Bitte gültige Nummer eingeben", fg="Red")
if __name__ == "__main__":
fenster = Tk()
fenster.title("Mathe-Spiel")
fenster.geometry("300x300")
app = Gui(fenster)
fenster.mainloop()

how can i control each button individually in tkinter

How can i control each button individually in tkinter?
Here is my code:
from tkinter import *
class Minesweeper:
def __init__(self,action):
L=[]
for i in range(15):
for j in range(15):
self.action = Button(win, text = " h ",command = self.clickMe)
self.action.grid(column = i, row = j)
def clickMe(self):
self.action.configure(foreground = "red")
def main():
global win
win = Tk()
win.title('Minesweeper')
game = Minesweeper(win)
win.mainloop()
main()
Better way is a binding some event to button:
from tkinter import *
class Minesweeper:
def __init__(self, action):
L=[]
for i in range(15):
for j in range(15):
self.action = Button(win, text="h")
# bind to button function 'clickMe' that runs while <Button-1> clicked on it
self.action.bind("<Button-1>", self.clickMe)
self.action.grid(column=i, row=j)
def clickMe(self, event):
"""changes the 'fg' color of the events widget"""
event.widget.configure(foreground="red")
def main():
global win
win = Tk()
win.title('Minesweeper')
game = Minesweeper(win)
win.mainloop()
main()

Tkinter create buttons from list each with its own function

I want to create buttons from a list and assign each button a function based on the list item. I tried below and the button doesn't respond to a click. I see solutions where a lambda function is used to pass a parameter to a function but I would like separate functions. Using Python 3.5 in Anaconda
import tkinter as tk
def North():
print('slected North')
def South():
print('slected South')
def East():
print('slected East')
def West():
print('slected West')
lst = ['North','South','East','West']
win = tk.Tk()
win.title = 'Compass'
for col,Direction in enumerate(lst):
butName = tk.Button(win, text = Direction, command = Direction)
butName.grid(row = 1, column = col)
win.mainloop()
Your list contains strings; it needs to contain functions
lst = [North,South,East,West]
Faster and better:
import tkinter as tk
def onbutton_click(label):
print('selected ', label)
lst = ['North','South','East','West']
win = tk.Tk()
win.title = 'Compass'
for col,Direction in enumerate(lst):
butName = tk.Button(win, text=Direction, command=lambda e=Direction: onbutton_click(e))
butName.grid(row=0, column=col)
win.mainloop()
or your way:
import tkinter as tk
def North():
print('slected North')
def South():
print('slected South')
def East():
print('slected East')
def West():
print('slected West')
lst = [North, South,East, West]
win = tk.Tk()
win.title = 'Compass'
for col,Direction in enumerate(lst):
butName = tk.Button(win, text=Direction.__name__, command=Direction)
butName.grid(row=0, column=col)
win.mainloop()
I also set the row as 0 cause there is no need to be 1.

NameError: name 'Menu' is not defined

I am trying to make a menubar for my GUI. I get this error:
`NameError: name 'Menu' is not defined`
I am not sure why this is happening, could someone please help me? My apologies, I am a beginner at python and tkinter.
from tkinter import Tk, BOTH
from tkinter.ttk import Frame, Button, Style
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.parent.title("xcal file.ics")
self.pack(fill=BOTH, expand=1)
self.centerWindow()
self.createMenuBar()
def centerWindow(self):
w = 500
h = 500
sw = self.parent.winfo_screenwidth()
sh = self.parent.winfo_screenheight()
x = (sw - w)/2
y = (sh - h)/2
self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y))
def createMenuBar(self):
menubar = Menu(Frame) #ERROR
menubar.add_command(label="Hello!", command=hello)
Frame.config(menu=menubar)
def main():
root = Tk()
ex = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
Menu is in the module tkinter, so you need to import it:
from tkinter import Tk, BOTH, Menu

Resources