Tkinter Label and Entry - python-3.x

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()

Related

Drag Drop List in Tkinter

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.

Tkinter buttons not changing back to the correct color after state changing to active

I am making this PDF tool, and I want the buttons to be disabled until a file or files are successfully imported. This is what the app looks like at the launch:
Right after running the callback for the import files button, the active state looks like this:
I want the colors of the buttons to turn maroon instead of the original grey. They only turn back to maroon once you hover the mouse over them. Any thoughts for how to fix this? Here is the callback for the import button:
def import_callback():
no_files_selected = False
global files
files = []
try:
ocr_button['state'] = DISABLED
merge_button['state'] = DISABLED
status_label.pack_forget()
frame.pack_forget()
files = filedialog.askopenfilenames()
for f in files:
name, extension = os.path.splitext(f)
if extension != '.pdf':
raise
if not files:
no_files_selected = True
raise
if frame.winfo_children():
for label in frame.winfo_children():
label.destroy()
make_import_file_labels(files)
frame.pack()
ocr_button['state'] = ACTIVE
merge_button['state'] = ACTIVE
except:
if no_files_selected:
status_label.config(text='No files selected.', fg='blue')
else:
status_label.config(text='Error: One or more files is not a PDF.', fg='red')
status_label.pack(expand='yes')
import_button = Button(root, text='Import Files', width=scaled(20), bg='#5D1725', bd=0, fg='white', relief='groove',
command=import_callback)
import_button.pack(pady=scaled(50))
I know this was asked quite a while ago, so probably already solved for the user. But since I had the exact same problem and do not see the "simplest" answer here, I thought I would post:
Just change the state from "active" to "normal"
ocr_button['state'] = NORMAL
merge_button['state'] = NORMAL
I hope this helps future users!
As I understand you right you want something like:
...
ocr_button['state'] = DISABLED
ocr_button['background'] = '#*disabled background*'
ocr_button.bind('<Enter>', lambda e:ocr_button.configure(background='#...'))
ocr_button.bind('<Leave>', lambda e:ocr_button.configure(background='#...'))
merge_button['state'] = DISABLED
merge_button['background'] = '#*disabled background*'
merge_button.bind('<Enter>', lambda e:ocr_button.configure(background='#...'))
merge_button.bind('<Leave>', lambda e:ocr_button.configure(background='#...'))
...
...
ocr_button['state'] = ACTIVE
ocr_button['background'] = '#*active background*'
ocr_button.unbind('<Enter>')
ocr_button.unbind('<Leave>')
merge_button['state'] = ACTIVE
merge_button['background'] = '#*active background*'
merge_button.unbind('<Enter>')
merge_button.unbind('<Leave>')
...
If there are any errors, since I wrote it out of my mind or something isnt clear, let me know.
Update
the following code reproduces the behavior as you stated. The reason why this happens is how tkinter designed the standart behavior. You will have a better understanding of it if you consider style of ttk widgets. So I would recommand to dont use the automatically design by state rather write a few lines of code to configure your buttons how you like, add and delete the commands and change the background how you like. If you dont want to write this few lines you would be forced to use ttk.Button and map a behavior you do like
import tkinter as tk
root = tk.Tk()
def func_b1():
print('func of b1 is running')
def disable_b1():
b1.configure(bg='grey', command='')
def activate_b1():
b1.configure(bg='red', command=func_b1)
b1 = tk.Button(root,text='B1', bg='red',command=func_b1)
b2 = tk.Button(root,text='disable', command=disable_b1)
b3 = tk.Button(root,text='activate',command=activate_b1)
b1.pack()
b2.pack()
b3.pack()
root.mainloop()
I've wrote this simple app that I think could help all to reproduce the problem.
Notice that the state of the button when you click is Active.
#!/usr/bin/python3
import sys
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
class Main(ttk.Frame):
def __init__(self, parent, *args, **kwargs):
super().__init__()
self.parent = parent
self.init_ui()
def cols_configure(self, w):
w.columnconfigure(0, weight=0, minsize=100)
w.columnconfigure(1, weight=0)
w.rowconfigure(0, weight=0, minsize=50)
w.rowconfigure(1, weight=0,)
def get_init_ui(self, container):
w = ttk.Frame(container, padding=5)
self.cols_configure(w)
w.grid(row=0, column=0, sticky=tk.N+tk.W+tk.S+tk.E)
return w
def init_ui(self):
w = self.get_init_ui(self.parent)
r = 0
c = 0
b = ttk.LabelFrame(self.parent, text="", relief=tk.GROOVE, padding=5)
self.btn_import = tk.Button(b,
text="Import Files",
underline=1,
command = self.on_import,
bg='#5D1725',
bd=0,
fg='white')
self.btn_import.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
self.parent.bind("<Alt-i>", self.switch)
r +=1
self.btn_ocr = tk.Button(b,
text="OCR FIles",
underline=0,
command = self.on_ocr,
bg='#5D1725',
bd=0,
fg='white')
self.btn_ocr["state"] = tk.DISABLED
self.btn_ocr.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
r +=1
self.btn_merge = tk.Button(b,
text="Merge Files",
underline=0,
command = self.on_merge,
bg='#5D1725',
bd=0,
fg='white')
self.btn_merge["state"] = tk.DISABLED
self.btn_merge.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
r +=1
self.btn_reset = tk.Button(b,
text="Reset",
underline=0,
command = self.switch,
bg='#5D1725',
bd=0,
fg='white')
self.btn_reset.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
b.grid(row=0, column=1, sticky=tk.N+tk.W+tk.S+tk.E)
def on_import(self, evt=None):
self.switch()
#simulate some import
self.after(5000, self.switch())
def switch(self,):
state = self.btn_import["state"]
if state == tk.ACTIVE:
self.btn_import["state"] = tk.DISABLED
self.btn_ocr["state"] = tk.NORMAL
self.btn_merge["state"] = tk.NORMAL
else:
self.btn_import["state"] = tk.NORMAL
self.btn_ocr["state"] = tk.DISABLED
self.btn_merge["state"] = tk.DISABLED
def on_ocr(self, evt=None):
state = self.btn_ocr["state"]
print ("ocr button state is {0}".format(state))
def on_merge(self, evt=None):
state = self.btn_merge["state"]
print ("merge button state is {0}".format(state))
def on_close(self, evt=None):
self.parent.on_exit()
class App(tk.Tk):
"""Main Application start here"""
def __init__(self, *args, **kwargs):
super().__init__()
self.protocol("WM_DELETE_WINDOW", self.on_exit)
self.set_style()
self.set_title(kwargs['title'])
Main(self, *args, **kwargs)
def set_style(self):
self.style = ttk.Style()
#('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
self.style.theme_use("clam")
def set_title(self, title):
s = "{0}".format('Simple App')
self.title(s)
def on_exit(self):
"""Close all"""
if messagebox.askokcancel(self.title(), "Do you want to quit?", parent=self):
self.destroy()
def main():
args = []
for i in sys.argv:
args.append(i)
kwargs = {"style":"clam", "title":"Simple App",}
app = App(*args, **kwargs)
app.mainloop()
if __name__ == '__main__':
main()

How can I directly access the next column in my treeview to insert data

I have set up a treeview to display data from my sqlite db. I am able to fill the first column with a query and now I need to fill the other columns with different queries.
# Top Container
top_frame = ttk.Frame()
top_frame.grid(column=0, row=0)
# create a treeview with dual scrollbars
list_header = ['First', 'Second', 'Third']
self.tree = ttk.Treeview(columns=list_header, show="headings")
vsb = ttk.Scrollbar(orient="vertical",
command=self.tree.yview)
hsb = ttk.Scrollbar(orient="horizontal",
command=self.tree.xview)
self.tree.configure(yscrollcommand=vsb.set,
xscrollcommand=hsb.set)
self.tree.grid(column=0, row=0, sticky=(N, S, E, W), in_=top_frame)
vsb.grid(column=1, row=0, sticky=(N, S), in_=top_frame)
hsb.grid(column=0, row=1, sticky=(E, W), in_=top_frame)
# Display the headers
for col in list_header:
self.tree.heading(col, text=col.title(), command=lambda c=col: sortby(self.tree, c, 0))
# adjust the column's width to the header string
self.tree.column(col)
# Display the data
query = ProjectNumber.select()
for item in query:
self.tree.insert('', 'end', values=item.project_num)
how can i access the next column and fill it with a separate query?
if I've understand, below you can see a working example of what you want to do.
The example is write in oo approach.
After launch the script click on Load button, you will see the treeview populate with
data that simulate a recordset ,list of a tuple. After try to click on a item of the
treeview and see what happens. I've add even click and double click event callback.
The data represent Italian pasta dishes.
import tkinter as tk
from tkinter import ttk
class App(tk.Frame):
def __init__(self,):
super().__init__()
self.master.title("Hello World")
self.init_ui()
def init_ui(self):
f = tk.Frame()
tk.Label(f, text = "Buon Appetito").pack()
cols = (["#0",'','w',False,200,200],
["#1",'','w',True,0,0],)
self.Pasta = self.get_tree(f, cols, show="tree")
self.Pasta.show="tree"
self.Pasta.pack(fill=tk.BOTH, padx=2, pady=2)
self.Pasta.bind("<<TreeviewSelect>>", self.on_selected)
self.Pasta.bind("<Double-1>", self.on_double_click)
w = tk.Frame()
tk.Button(w, text="Load", command=self.set_values).pack()
tk.Button(w, text="Close", command=self.on_close).pack()
w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=0)
f.pack(side=tk.LEFT, fill=tk.BOTH, expand=0)
def set_values(self,):
#.insert(parent, index, iid=None, **kw)
rs = [(0,'Spaghetti'),(1,'Rigatoni'),(2,'Pennette')]
for i in rs:
#print(i)
pasta = self.Pasta.insert("", i[0], text=i[1], values=(i[0],'pasta'))
rs_dishes = self.load_dishes(i[0])
if rs_dishes is not None:
for dish in rs_dishes:
#print(dish)
wards = self.Pasta.insert(pasta, dish[0],text=dish[1], values=(dish[0],'dishes'))
def load_dishes(self, i):
rs = [(0,'Spaghetti aglio e olio'),
(1,'Rigatoni alla matriciana'),
(1,'Rigatoni al pesto'),
(1,'Rigatoni alla norma'),
(2,'Pennette al pesto'),
(2,'Pennette alla wodka'),
(2,'Pennette al tartufo'),
(0,'Spaghetti allo scoglio'),
(0,'Spaghetti al pesto'),
(0,'Spaghetti alla carbonara'),
(0,'Spaghetti alla puttanesca')]
r = [x for x in rs if x[0] == i]
return r
def on_selected(self, evt=None):
selected_item = self.Pasta.focus()
d = self.Pasta.item(selected_item)
if d['values']:
if d['values'][1]=='dishes':
pk = d['values'][0]
print("pk: {}".format(pk))
def on_double_click(self, evt=None):
if self.Pasta.focus():
item_iid = self.Pasta.selection()
pk = self.Pasta.item(self.Pasta.focus())['text']
print(item_iid, pk)
def get_tree(self,container, cols, size=None, show=None):
headers = []
for col in cols:
headers.append(col[1])
del headers[0]
if show is not None:
w = ttk.Treeview(container,show=show)
else:
w = ttk.Treeview(container,)
w['columns']=headers
for col in cols:
w.heading(col[0], text=col[1], anchor=col[2],)
w.column(col[0], anchor=col[2], stretch=col[3],minwidth=col[4], width=col[5])
sb = ttk.Scrollbar(container)
sb.configure(command=w.yview)
w.configure(yscrollcommand=sb.set)
w.pack(side=tk.LEFT, fill=tk.BOTH, expand =1)
sb.pack(fill=tk.Y, expand=1)
return w
def on_close(self):
self.master.destroy()
if __name__ == '__main__':
app = App()
app.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()

migrate tkinter code to pyqt

I am trying to migrate the code below (which is in tkinter) to pyqt. I am very new to pyqt. I could not get much details.
import os, sys, time
import os.path
import shutil
import sys
import Tkinter as tk
from Tkinter import *
root = Tk()
frame = Frame(root)
def enable_():
# Global variables
if (var.get()==1):
E5.config(state=NORMAL)
E5.insert(0, 1)
for c in checkbuttons:
c.config(state=NORMAL)
# disable test selection
else:
E5.delete(0, END)
E5.config(state=DISABLED)
for c in checkbuttons:
c.config(state=DISABLED)
# Select geometry
root.geometry("500x570+500+300")
root.title('Test Configure')
# Global variable declaration
global row_me
global col_me
row_me =9
col_me =0
L1 = Label ().grid(row=0,column=1)
Label (text='Target IP Address').grid(row=1,column=0)
E4 = Entry(root, width=20)
E4.grid(row=1,column=1)
L1 = Label ().grid(row=2,column=1)
variable = StringVar()
# Check button creation
var = IntVar()
var_mail = IntVar()
# Create check buttons
R1=Checkbutton(root, text = "Enable Test Suite Selection", variable = var, \
onvalue = 1, offvalue = 0, height=1, \
width = 20, command=enable_)
R1.grid(row=3,column=1)
R2=Checkbutton(root, text = "Send Email", variable = var_mail, \
onvalue = 1, offvalue = 0, height=1, \
width = 20)
R2.grid(row=3,column=2)
L5 = Label (text='Number of Loop').grid(row=4,column=0)
E5 = Entry(root, width=5)
E5.grid(row=4,column=1)
E5.config(state=DISABLED)
L2 = Label ().grid(row=21,column=1)
# List of Tests
bottomframe = Frame(root)
bottomframe.grid(row=24,column=1)
# Reset Button
configbutton = Button(bottomframe, text="Reset", fg="black")
configbutton.grid(row=24,column=2,padx=5, pady=0)
# Quit Button
configbutton = Button(bottomframe, text="Quit", fg="red")
configbutton.grid(row=24,column=3)
# Submit Button
blackbutton = Button(bottomframe, text="Submit", fg="black")
blackbutton.grid(row=24,column=4,padx=5, pady=0)
#Check buttons for test suite selection
test_suite_name=[name for name in os.listdir(".") if (os.path.isdir(name) and name.startswith('test-') )]
L34 = Label (text='Select Test Suite To Be Executed').grid(row=7,column=1)
L11 = Label ().grid(row=9,column=1)
row_me =9
col_me =0
checkbuttons = [create_checkbutton(name) for name in test_suite_name ]
for c in checkbuttons:
c.config(state=DISABLED)
# initiate the loop
root.mainloop()
I have written this code but I am not sure how to make the grid and location for each widget in pyqt:
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
SubmitButton = QtGui.QPushButton("OK")
CancelButton = QtGui.QPushButton("Cancel")
ResetButton = QtGui.QPushButton("Reset")
edit1 = QLineEdit()
edit2 = QLineEdit()
cb = QtGui.QCheckBox('Enable Test suite selection', self)
cb.move(150, 100)
#cb.stateChanged.connect(self.changeTitle)
cb2 = QtGui.QCheckBox('Send mail', self)
cb2.move(300, 100)
# cb2.stateChanged.connect(self.changeTitle)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(SubmitButton)
hbox.addWidget(CancelButton)
hbox.addWidget(ResetButton)
hbox.addWidget(edit1)
hbox.addWidget(edit2)
hbox.addWidget(cb)
hbox.addWidget(cb2)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
self.setLayout(vbox)
self.setGeometry(100, 100, 500, 650)
self.setWindowTitle('HMI')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Thank you!
You can either do the designing part in your code or through a QT Designer which ships with PyQt4. and some examples can be found in the path C:\Python26\Lib\site-packages\PyQt4\examples and documentation in the path C:\Python26\Lib\site-packages\PyQt4\doc\html\modules.html if you are using windows. Hope this helps.

Resources