This is my first question on stack overflow, so kindly forgive me for any mistakes i might've made. I am working on a project which uses both mediapipe as well as Ursina (to make a motion-capture game in python). I tried to use both the libraries but only one window pops up (based on which is placed first, if ursina is placed first the game opens and if mediapipe code is placed first the camera opens). To fix this problem, i have used the "multiprocessing" library to open both at once.
here is a sample code :
from anotherfile import mediapipe_code
#this file:
def setup():
app = Ursina() #and all other default setup
def update():
# this is the problem
if __name__ == "__main__":
proc1 = multiprocessing.Process(target=mediapipe_code)
proc2 = multiprocessing.Process(target=setup)
proc1.start()
proc2.start()
proc1.join()
proc2.join()
Both the windows open just fine but the update function doesn't run. So is there any way to fix this? ik it was a long story im sorry :)
I have tried putting the update function in another process but it runs only once. I want to run every frame like it normally does.
Related
The people who are familiar with the Live Server of VS Code, would have easily understood what is the main motive of this question.
But for others, here's the explanation:
Main motive of Live Server is to Automatically Reload Your Site on Save in web development! (Which get changed for python tkinter).
When ever I change something in my python file which contains tkinter code, the change should be reflected in the main window (the main window should not re-open to reflect the changes).
I have tried to search on web as well as on stack over flow, but all the results are for updating value in entry, label, buttons etc. But what I want is, the whole window should be updated when ever I change something in my main file, and the main window should not be reopened to do so. So in short, updating whole window without closing it, on every changes in the main file or automatically reload your program on save without reopening!
What have I tried?:
I tried to detect change in file using os.getsize which satisfied the first part of my question, but however I am not able to solve the second part i.e window should not be closed.
import os
main__tkinter_filename="myfile.py"
initial_filesize=os.path.getsize(main_tkinter_filename) # Getting size of the file for
# comparison.
while 1:
final_filesize=os.path.getsize(main_tkinter_filename)
if final_filsize<intial_filesize or final_filesize>initial_filesize:
webbrowser.open(main_tkinter_filename)
Example:
from tkinter import *
root=Tk()
root.mainloop
results in the below GUI:
If i have added a=Label(text='text')anda.pack() after root=Tk(), it should show me the label, and if i have removed the same code, it should remove them.
I will answer your question by the best of my understanding,
I have some (a few projects of my own, still way too limited) experience with flutter which has hot-reload feature (same as you described above, which you want with python, mainly tkinter), I recently switched to python for gui (Loved it!), so I would like to share my research here:
I was successfully able to set up hot-reload both with kivy (kivymd hot reload, which comes with watchdog and kaki, which works real-time), and with tkinter, while there is a hitch with the later, you will have to press Ctrl + R as to reload the tkinter window, but it works without having to re-run the python program, I will leave the link to the found resources here, hope it helps with your query!
To setup hot-reload with tkinter (requires Ctrl + R), please refer here.
To setup hot-reload with kivy/kivymd (real-time), which I personally prefer, you can find the official docs here.
To mention, I use the above on Manjaro (Arch linux) with pycharm, atom, but I have also tried and have made it run successfully on Windows 10 with vs code (worked like charm)
Hope I could be of help! If you face any problem regarding the same, please feel free to ask! Thanks!
After digging around I have finally found out a way to implement hot reload feature (which #Stange answers provides) but just updating the selected frame or code.
The basic idea is constanly reading the file and executing the selected code, and removing the object in a list which are meant to be removed.
# Live Checker.py
import keyboard
while 1:
if keyboard.is_pressed("Ctrl+r"):
with open('test.py','r') as file:
file_data=file.read()
file_data_start_index=file_data.find("'#Start#'")
file_data_end_index=file_data.find("'#End#'")
exec_command=file_data[file_data_start_index:file_data_end_index]
with open('exec_log.txt','w') as txt_file:
txt_file.write(exec_command)
Here I am constantly checking if if ctrl+r key is pressed, and if pressed
it reads the file,
writes the selected code from the file into a txt file.
I have specified the start and end of the code to be updated by #Start# and #End# respectively.
# Main.py
def check():
with open('exec_log.txt','r') as exec_c:
exec_command=exec_c.read()
if len(exec_command)==0:
pass
else:
print(exec_command)
exec('for i in root.winfo_children():i.destroy()\n'+exec_command)
print('exec')
with open('exec_log.txt','w') as exec_c:
pass
root.update()
root.after(100,check)
root.after(100,check)
And in the main file, i have added the above code which continusly check if exec_log.txt file has any changes, and if changes are there, then it executes them and all so destroys the widget specified in the remove_list.
This is just a temporary solution which in my case helps me to implement the hot reload feature in tkinter.
I am making turn based game in python using Pyglet. The game has a player-vs-AI mode in which the bot calculates a move to play against the player. However, the function which calculates the bot's move takes around 3-5 seconds to run, blocking the game's UI. In order to get around this, I am running the bot's calculation on a second process using multiprocessing.Process. I got it to work well without blocking the UI, however every time I open the second process to run the function a new Pyglet window opens, then closes again when the process is closed. Is there any way to open a second process in a Pyglet program without a second window opening? Let me know if examples of my code is required, and I will try to come up with similar code to share. Thanks in advance to anyone who can help.
You can fix the problem by moving the initialization of the window inside of the main block
I am modifying a nice Chess game that I found here.
This game is initialized this way:
root = tk.Tk()
app = App(root)
app.canvas.bind("<Button-1>", app.callback)
root.mainloop()
This initialization provide a GUI with a chessboard. Every time that I move a piece, a
def callback(self,event)
def displayBoard(self):
is triggered and make all the magic (move the piece, check if is a valid move, and etc)
This is working fine. However, I would like to change this so I can also trigger this function by, for example, the command line.
Explaining in better detail, I wanna be able to move a piece of the chessboard not only by the user input via the GUI but also typing commands (e.g. move to position x,y) instead of only being able to play via GUI.
Is this a possible change or would I have to change the whole core?
I am working for the first time towards the implementation of a very simple GUI in PyQt5, which embeds a matplotlib plot and few buttons for interaction.
I do not really know how to work with classes so I'm making a lot of mistakes, i.e. even if the functionality is simple, I have to iterate a lot between small corrections and verification.
For some reason I would like to debug, however, the whole process is made much, much slower by the fact that at any other try, the python kernel dies and it needs restarting (all done automatically) several times.
That is, every time I try something that should last maybe 5 secs, I end up spending a minute.
Anybody know where to look to spot what is causing these constant death/rebirth circles?
I have been using spyder for some time now and I never experienced this behaviour before, so I'm drawn to think it might have to do with PyQt, but that's about how far I can go.
This issue is tracked here
You can learn all the details there, but in a nutshell when running from inside spyder - which itself is a QApplication, the main loop should read:
if __name__ == '__main__':
import sys
from PyQt5 import QtWidgets
fig1 = Figure()
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
main = Main()
main.addmpl(fig1)
main.show()
sys.exit(app.exec_())
The if/then check on the existence of a QApplication avoids a segmentation fault which happens if one tries to launch multiple instances at one time, as explained here
I had a similar problem and found that my application only worked when the graphics settings inside Spyder are set to inline. This can be done at Tools -> Preferences -> IPython console -> Graphics, now change the Backends to inline.
Hope this helps.
I've been fighting with Tkinter for a while now and have exhausted most the resources I have for referencing this. I've found a couple similar topics here but none quite bring me to where I need to be.
I've got a long running (not long actually, it only takes 10-12 secs) python script that silently install an application using subprocess from the CLI. Subprocess worked and it successfully installed the application, however, the GUI locks (i.e hangs/freeze) after the execution (and the program no longer run the succeeding code). I know I have to use threading here but I've already tried using it to no avail.
As part of my learning process, I cloned a repo from Github and modify it to run on Windows (since it only run in MAC platform) and planning to extend it, and this is the part where I got stucked. This is my first time to use TKinter and I apologize if I have missed something stupid or not asked the question in the right way. Hope you can help me and thank you in advance for the assistance.
Code can be found on this link.
You have defined a button
installButton = Button(bottomFrame, text=installButtonTxt,
command=on_install_thread, width=9)
with command handler
def on_install_thread():
...
loop_thread = threading.Thread(target=on_install_button_active,
args=['button', 'model', itemSelectCount])
and the target for thread on_install_button_active.
Then
def on_install_button_active(button, model, selectcount):
...
# Reset install status
installStatus = 'complete'
# Remove Cancel Button
cancelButton.destroy()
# Activate Install/Done button and menus
installButton.configure(state=NORMAL)
# menuControl('normal')
refreshGui(mainWindow)
It looks like there is code at the end of on_install_button_active that involves Tkinter
widgets. Calling tkinter methods from other threads seems to be unreliable, for example 1.
It is possible to define virtual events
def renderMainWindow():
...
mainWindow.bind('<<InstallComplete>>', on_install_complete)
def on_install_complete():
cancelButton.destroy()
installButton.configure(state=NORMAL)
def on_install_button_active(button, model, selectcount):
...
# Reset install status
installStatus = 'complete'
mainWindow.event_generate('<<InstallComplete>>', when='tail')
If there are other calls in that thread that involve Tkinter widgets, it might be better to remove them.
I was able to resolved problems with my GUI by using mtTkinter and by referring to this post.