I want to save changes to a file, when it's not open the button must be green onclick and when it's open the button must be red onclick until I close the file. But I got the error that my tkinter button doesn't become red. Here is my code:
tryit = True
while tryit == True:
try:
wb.save(saved_file)
save_to_file_button.config(activebackground="green")
time.sleep(0.5)
tryit = False
except:
save_to_file_button.config(activebackground="red")
time.sleep(1.0)
tryit = True
You cannot use an infinite loop in a GUI handler. When you create or change a GUI element, nothing gets drawn. Instead, that just sends a message to the component. The messages are fetched and dispatched when the code gets back to the main loop. As long as you are in your loop, Tk can't get back to its main loop, and your UI is frozen.
If you need periodic stuff like this, you need to use root.after to request a callback after some period of time. For example (you didn't give enough details for me to fill in the correct names, but this is the idea):
def savefile(self):
try:
wb.save(saved_file)
save_to_file_button.config(activebackground="green")
except:
save_to_file_button.config(activebackground="red")
root.after( 1.0, self.savefile)
It takes a different coding philosophy to work in an event-driven system.
When visiting some websites with selenium there are times where the page doesn't load correctly. So I want to write a code that checks if the website loaded correctly by searching for a particular button. If it can't find the button it needs to refresh until it finds the button and if the code does find the button it needs to execute the rest of the code.
So for example: Button not there: >>> refresh >>> (checks again if button is not there) Button not there >>> refresh >>> (checks again if button is not there) Button is there >>> rest of code
The loop that I currently have looks like this but after refreshing the loop doesn't restart and runs the else: function.
So the question is how do I make a loop that restarts the loop after it refreshes.
while not (driver.find_elements(By.CLASS_NAME, "button")):
driver.refresh()
else:
Rest of code
Help would be much appreciated, thanks in advance
You can have an infinite while loop, and an if condition with find_elements, Please note that find_elements does not return any exception, it returns a list of web elements or either 0.
Code:
while True:
try:
if len(driver.find_elements(By.XPATH, "xpath of the button")) >0:
print("Button is present, since find elements list is non empty")
# execute the code, may be click on the button or whatever it is.
#make sure to exit from infinite loop as well
break
else:
driver.refresh()
#may be put some delay here to let button available to click again.
except:
print("There was some problem trying to find the button element, tearing it down")
break
I have a GUI with alot of buttons/widgets. I want that if 30 secs passes and the user didnt hit anything on the GUI that it will automaticly go back to the first screen.
I added this between root = Tk() and root.mainloop()
root.after(30000, lambda: showFirstScreen())
This line will go to my first screen after 30 seconds even if you hit the screen. So there is no counter that resets after hitting a button/widget.
I try'd to add it to a specific button on a other window so:
button13.after(30000, lambda: showFirstScreen())
If I reach the page with the button it will move to the main window after 30 seconds. But If I go back to the button it wont repeat the action above.
Any idea what im doing wrong?
You could use a variable to check if the user interacts with widgets, something like,
def showFirstScreen(buttons_pressed):
if buttons_pressed==True:
...code to go to first screen...
Use the buttons_pressed variable inside all your buttons' call methods to check if the user has used any button.
If you want to add after() to a button on another window, you can use a separate function,
button13_onPress():
if buttons_pressed==True:
root.after(30000, lambda: showFirstScreen())
I have a click button that I want to change events when the button is pressed. A minimal version of the existing code looks like this:
# Event that happens the first time
def first_event(self):
button.setText("Second Event")
button.clicked.connect(second_event)
# Event that happens the second time
def second_event(self):
button.setText("First Event")
button.clicked.connect(first_event)
button = QtGui.QPushButton("First Event")
button.clicked.connect(first_event)
Unfortunately, instead of changing the event that happens, it simply adds and event to the clicked signal, meaning that the following happens:
First button press - calls first_event
Second button press - calls first_event and second_event
Third button press - calls first_event twice and second_event
etc...
My desired behavior would be to have the button change functions when it is pressed, so that the resulting behavior would be:
First button press - calls first_event
Second button press - calls second_event
Third button press - calls first_event
etc...
Is there a way to make it so that it changes the click event instead of adding a new one? Is there a way to remove events after the fact?
I found a way to separate old events from signals using the disconnect() method. Here is an edited version that accomplishes what I originally wanted to do:
# Event that happens the first time
def first_event(self):
button.setText("Second Event")
button.clicked.disconnect()
button.clicked.connect(second_event)
# Event that happens the second time
def second_event(self):
button.setText("First Event")
button.clicked.disconnect()
button.clicked.connect(first_event)
button = QtGui.QPushButton("First Event")
button.clicked.connect(first_event)
It's worth noting that instead of doing this, I eventually did what ekhumoro mentioned in the comments, and created a wrapper function with a flag to record the current state, and then call first_event() or second_event() based on the value of the flag.
I am attempting for a homework assignment to implement Simon Says in python. I'm trying to do it using the turtle library (a requirement).
However, I've run into a stumbling block in that while I can get the screen to register click events (currently just printing the x,y coordinates) I can't get it to wait for a click event.
Specifically what I'm planning on doing is having areas on the screen that when they click within that location it is considered as if they had clicked a button. Screen clears and game does whatever.
However, in experiments in trying to get a working 'button' all that it does is set it so it prints the x,y coordinates but the rest of the program finishes. Didn't wait for the user to click anything. I tried a blocking method of...
while clicked == False:
pass
or
while clicked == False:
time.sleep(1)
but both methods hangs the program until I manually interrupt and then it'll print the clicks.
Am I missing an option somewhere?
Turtles don´t have buttons, but they do have callbacks for clicks.
Furthermore, you should use onclick for Screen to detect general clicks and onclick for turtle to detect clicking in turtles. You can, for example, make a 4 BIG turtles with different colors by using a dynamic shape.
Also, turtle is based on Tk, so you must be aware of things like mainloop()
The following program give some hints for Python 2.7.5.
import turtle as t
from random import randint
class MyTurtle(t.Turtle) :
def __init__(self,**args) :
t.Turtle.__init__(self,**args)
def mygoto(self,x,y) :
t1.goto(x,y)
print x,y
def randonics(self,x,y) :
self.left(randint(90,270))
def minegoto(x,y) :
print x,y
t1.goto(x,y)
wt=t.Screen()
t1=MyTurtle()
wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
t1.shape("big")
wt.onclick(t1.mygoto,btn=1)
wt.onclick(minegoto,btn=2)
t1.onclick(t1.randonics,btn=3)
t1.goto(100,100)
t.mainloop()
So after extensive search there isn't necessarily a way pause execution of the code in python while using turtle to wait for some click event. Maybe in Tk I could do that but not in turtle.
However, there is a way to get around that. As an example. A method sets up the fake button on the screen, sets the click event, and terminates. The click event when clicked calls the next method needed for execution. So until the button is clicked the actual code isn't doing anything but remains in memory for use.
So more specifically.
1. Create a 'button'.
2. Have your program behave normally until it needs to wait for a click event.
3. Set up the on screen click (or on turtle) in such a way when the 'button' is clicked the next part of the code is run.
Special note. The code in question can't depend on waiting for a click event for later on in code. Instead, the click causes the next part of the execution of your code.
You can make the function registered with onclick() test the x,y position. If it is inside some region you do whatever you must.
I don´t see the difference between what you want to do and what this code does, the modification of turtle position is just an example, you can do anything when a click is captured by onclick(), even start a thread if you really need it (using Creating Threads in python)
import turtle as t
from random import randint
from threading import Thread
from time import sleep
def threaded_function(arg,t1):
for i in range(arg):
print "running",i
sleep(1)
t1.forward(i*10)
def minegoto(x,y) :
print x,y
t1.goto(x,y)
thread = Thread(target = threaded_function, args = (10,t1 ))
thread.start()
thread.join()
print "thread finished...exiting"
wt=t.Screen()
t1=t.Turtle()
wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
t1.shape("big")
wt.onclick(minegoto,btn=1)
t1.goto(100,100)
t.mainloop()