pack_configure() missing 1 required positional argument: 'self' - python

I actually don't know why it does this but something is wrong with root = Label(master,text =(click))
Label.pack()
but basically what this program does is simple its just a clicker game and thing is everything else works its just when im trying to add a counter to count how many clicks a user has clicked it doesnt work
from tkinter import *
import time
from tkinter import messagebox
master = Tk()
def uiPrint():
info()
print("")
print(click)
blankLine()
Label_1 = Label(text = "Double click purchases need 50 clicks!")
Label_1.pack()
click = 0
mult = 1
dcp1 = 0
def blankLine():
for i in range(20):
print("")
def purchaseDoubleClicksCommand():
global click
global mult
if click < 50:
messagebox.showinfo("showinfo", "Not enough clicks!")
elif click >= 5:
mult = mult+1
click = click - 50
messagebox.showinfo("showinfo", "Double Clicks Purchased!")
def buttonCommand():
global click
global mult
click += 1*(mult)
root = Label(master,text =(click))
Label.pack()
mainClickButton = Button(master, text="Click!", command = buttonCommand)
mainClickButton.pack()
purchaseDoubleClickButton = Button(master, text="Purchase Double Clicks", command = purchaseDoubleClicksCommand)
purchaseDoubleClickButton.pack()
master.title("Clicker!")
master.geometry("%sx%s+%s+%s" % (400,100,512,512))
mainloop()

It seems that you are calling an instance method without an active instance:
Label.pack()
It is only possible for methods that are callable from the class itself and doesn't require an active instance/object e.g. methods decorated with #classmethod and #staticmethod. Thus change it to:
root.pack()
With the instance root, the self argument would automatically be passed as first argument, which references the root object itself.

Use root.pack() instead of Label.pack()

Related

Python tkinter Buttons are 'out of place' / not working properly

Hello avid python users...
I was trying to create my first GUI writing a tic-tac-toe program but I ran into a problem regarding the 9 buttons on the grid. Here is part of the code that generates the buttons:
button = 0
for x in range(3):
for y in range(3):
button = Button(root, text= " ", font=("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command=lambda button=button: b_click(button))
button.grid(row = x, column = y)
The click function looks like this:
def b_click(b):
global clicked
if b["text"] == " " and clicked == True:
b["text"] = "X"
clicked = False
elif b["text"] == " " and clicked == False:
b["text"] = "O"
clicked = True
else:
messagebox.showerror("Tic Tac Toe", "Hey! That box has already been selected \nPick another box...")
My problem is that whenever I click a button on the GUI it selects and use b_click(b) on the button to the left of whichever one I originally picked...
Help would be appreciated...
Look at this script:
import tkinter as tk
from functools import partial
def b_click(button):
button.config(text="X")
root = tk.Tk()
for x in range(3):
for y in range(3):
button = tk.Button(root, text=" ")
command = partial(b_click, button)
button.config(command=command)
button.grid(row=x, column=y)
root.mainloop()
It uses functools.partial and <tkinter.Button>.config(...) to pass in the button to the function. From there you can do anything you like with the button.
Edit:
functools.partial is like a labmda but you don't need the button=button part. It takes at least 1 argument (the function name) and the rest of the arguments/key word arguments are passed to the function when it is called.
So
x = partial(function, arg1, arg2, kwarg1="")
x(arg3)
will be the same as function(arg1, arg2, arg3, kwarg1="text").

Is there a way to know if Tkinter optionmenu dropdown is active ?

I'm writing a Tkinter program where I have an option menu with other UI elements. I have a requirement that if optionmenu drop down remains active for a particular time (say 1 minute), I need to close drop down menu and cancel the selection. I was wondering if there is a way to know if an optionmenu dropdown is active. I've looked at this particular link but couldn't locate any specific method for what I need.
Keeping track of whether the menu is closed or open is easily done with a command and click binding. The hard part is forcing the menu to close. Either a physical mouse click off the widget or press of Escape will do so. But generating events does not do. The #commented_out bits below are failed experiments.
import tkinter as tk
root = tk.Tk()
n = 2
after_id = None
menu_open = False
omvar = tk.StringVar(root)
def timeout():
print('timeout called')
omvar.set('')
#root.event_generate('<Key-Escape>', keysym='Escape', keycode=9)
#om.destroy()
#root.event_generate('<FocusIn>')
#root.focus_get()
#root.event_generate('<Button-1>', x=10, y=20)
root.update()
def open(event):
print('open called')
global after_id, menu_open
after_id = root.after(n*1000, timeout)
menu_open = True
def close(val):
print('closed by', val)
global after_id, menu_open
root.after_cancel(after_id)
after_id = None
menu_open = False
om = tk.OptionMenu(root, omvar, 'a', 'b', 'c', command=close)
om.bind('<Button-1>', open)
om.pack()
root.mainloop()
A MenuButton + Menu would look nearly the same and might be easier. Would you consider that?
First define a variable,(for example: ddo = 0)
Then Trigger a click on your dropdownlist, when clicked, toggle ddo = 1(if ddo == 1 then ddo = 0)
and when ddo == 1 a timer start to count for 1second, after that 1second if ddo == 1, then close selectbox(for example by focusing on another element) and do what ever you want. an example pseudo code is here:
def OnClick(event):
if(ddo == 0):
ddo = 1
startTimerForOneSec(whenFinished=finishTimer())
else:
ddo = 0
def finishTimer():
if(ddo == 1):
focusOneSomeOtherElements()
doSomeThingElse()

GUI program not working PYTHON

I was trying to make a simple GUI based game that has a button having the text CLICK ME .Whenever the user clicks on the button the total number clicks are displayed on the button.
Here is my code
from Tkinter import *
class Application(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.grid()
self.bttn_click = 0
self.create_widget()
def create_widget(self):
self.bttn = Button(self)
self.bttn["text"] = "Total Clicks = 0"
self.bttn["command"] = self.update_count()
self.bttn.grid()
def update_count(self):
self.bttn_click += 1
self.bttn["text"] = "Total Clicks = " + str(self.bttn_click)
#main
root = Tk()
root.geometry("900x700")
root.title("Click Counter")
app = Application(root)
root.mainloop()
Please read it from the official documentation. In there, the first "Hello World" Example has almost the same code as you do.
The command self.bttn["command"] = self.update_count() assigns the return value of def update_count(self) to your button command.
If you think to know what the result of some action should be, you could always use a print statement afterwards to verify what your assignment did.
self.bttn["command"] = self.update_count()
print(self.bttn["command"])
What exactly is the issue and where does it come from?
in the code line of yours mentioned above, you are immediately calling self.update_count and not assigning the function to be called everytime the button is pressed.

When using tkinter in Python 3, how do you get a button to run a function each time it is pressed?

import tkinter as tk
panel = tk.Tk()
num = 42
lbl1 = tk.Label(panel, text = str(num))
Let's say I have a function and button like this:
def increase():
lbl1.configure(text = str(num+1))
btn = tk.Button(panel, text = 'Increase', command = increase)
panel.mainloop()
This button will make the number that is the label increase by 1 when pressing the button. However, this only works once before the button does absolutely nothing. How can I make it so that every time I press the button, the number increases by 1?
You never saved the incremented value of num.
def increase():
global num # declare it a global so we can modify it
num += 1 # modify it
lbl1.configure(text = str(num)) # use it
It's because num is always 43
import tkinter as tk
num = 42
def increase():
global num
num += 1
lbl1.configure(text = str(num))
panel = tk.Tk()
lbl1 = tk.Label(panel, text = str(num))
lbl1.pack()
btn = tk.Button(panel, text = 'Increase', command = increase)
btn.pack()
panel.mainloop()

How to refresh the GUI window in Tkinter

Im trying to make a simple GUI with Tkinker that, when you press a button it adds 1 to the text on a label. However, the label simply remains at 0. Is there a way I can refresh it so it stays up-to-date?
heres what i have so far:
from Tkinter import *
clicks = 0
def click():
global clicks
global Window
clicks += 1
print 'ok', clicks
def close_window():
global Window
Window.destroy()
Window = Tk()
Number = Label(text = clicks)
close = Button(Window , text='exit' , command = close_window)
button = Button(Window,text = 'clickme' ,command = click)
button.pack()
close.pack()
Number.pack()
Window.mainloop()
clicks += 1 only changes the variable clicks.
Use Label.config(text=...) or Label['text'] = ... to change the label text.
def click():
global clicks
clicks += 1
Number.config(text=clicks) # <------
print 'ok', clicks
You almost have it, but for your label you don't want to use "text", you want "textvariable". However, this takes a StringVar as a variable, which forces a little bit of busywork:
Window = Tk()
strclicks = StringVar()
Number = Label(textvariable=clicks)
and within click():
clicks += 1
strclicks.set(clicks)
Using "text" evaluates the variable at creation; "textvariable" updates the label when the variable updates.

Categories