I am writing a server/client encrypted chat service and have decided to spruce up my server code using Tkinter to display connected addresses. However, because of the Tkinter aspect, it's all that runs. I was wondering if I could run both simultaneously. I am already using .after() to update the client list every 5 seconds. I am already using threading to manage connections. Is threading a valid way to run both easily?
My two main piece of code that need running here are:
window.mainloop()
and
if __name__ == '__main__':
SERVER.listen(7)
client_thread = Thread(target=accept_connections)
client_thread.start()
client_thread.join()
SERVER.close()
Related
I'm trying to create a Python Tkinter GUI for a simple data transmission between an Arduino and a PC via Serial communication (I'm using pySerial package). I can input and send data from the GUI to the Arduino correctly. In a separated code file, I can also read data sent from Arduino correctly, but I have a problem with integrating this real-time data reading feature into the Tkinter GUI program and display it on the GUI. From my experiment, to properly read data sent from the Arduino, the reading need to be run in a loop. Tkinter also has its own loop. So to avoid being stuck in the data reading loop, I've been trying to run them in parallel using concurrent.futures, but it still doesn't work as I want. Please help!
Here's my code: https://drive.google.com/file/d/1xHOV-qXjg2iEA-PXa52d1_66bOpdbnzv/view?usp=sharing
(Please understand that I'm still learning Python, Tkinter and multiprocessing. So there could be some mistakes on conventions and terminology.)
And this is what the GUI looks like:
Arduino-PC Serial Communication GUI
Tkinter windows have a after method that can be used to run your own code as part of the Tkinter loop, for example:
from tkinter import Tk
window = Tk()
def do_something():
print("doing something!")
window.after(1000, do_something) # every 1000 milliseconds
# start the do_something function immediately when the window starts
window.after(0, do_something)
window.mainloop()
Every UDP server example I can find uses a while True loop to listen for incoming data. I'm attempting to use a single UDP socket server as part a kivy window that's also doing other things. As soon as I implement the server's while True loop everything locks up, as I guess I would expect it to do.
How do I listen on a UDP port and also have the rest of the program continue functioning?
I've tried moving the UDP server handling to another (udp_server.py) file and then importing the function, but since I'm importing the while loop nothing changes.
I've also tried assigning the received data to a variable inside udp_server.py and then just importing that variable, with udp_server.py already running separately, but even that is locking up my main program.
I'm 99.99% sure it's just some basic thing that I should already know, but I'm new to Python. Thanks in advance for any help.
Thank you Chris!!!!!!
I'm sure I'm understating the complexity of threading, but it works great now and the only thing I had to add was:
def thread_function():
from udp_server import amx_rx
# do stuff with amx_rx...
# class TouchPanel stuff...
if __name__ == '__main__':
x = threading.Thread(target=thread_function, daemon=True)
x.start()
try:
TouchPanel().run()
except KeyboardInterrupt:
raise
Now I have a running program with a UDP socket listening in the background! Thank you!!!
I'm trying to create a smart TV using a Raspberry Pi 3B+. I plan on using Tkinter to create a GUI for the TV and flask to create a remote that can be accessed via a smartphone.
I plan on running Flask and call the Tkinter via a subprocess. The issue I'm facing is when I need to pause a video, for example. The Flask process must interrupt the Tkinter subprocess to pause the video. I can't seem to find any solutions to how this might be done. One idea I had was to send a keyboard interrupt and handle pause\play, but since other forms of interrupts are also required such as volume and seek, I will need multiple different interrupts with data such as seek time, etc as well.
How can this be achieved using python subprocesses?
You need to send signals between two processes. You can probably use celery for that. Or use a simple sqlite database shared by both processes. the Flask process writes, the tkinter reads changes
Or look at this: https://pymotw.com/2/multiprocessing/communication.html
I am making a Non-malicious Twitch TV bot that runs a few commands in chat. I have been using the bot for 2 months and decided to create a small GUI for basic changes to variables whilst it is running. Both the GUI and the Bot work fine separately but I am having issues making them work together.
I have used Tkinter to create the GUI and it requires a Loop to make the window remain open. This loop therefore stops the rest of the code continuing on and launching the bot. I need to work out how to keep the loop running but also continuing on to the rest of the Bot and run that behind the GUI.
This is the start of the Bot where it launches the GUI;
app = Geekster_Bot_GUI(None)
app.title('Geekster_Bot')
app.geometry('450x100')
app.mainloop()
It then continues to the bot connecting to the IRC.
How do I continue after the mainloop()?
You can use threading or multiprocessing. Simple example:
import Tkinter
import threading
def create_frame():
MessFrame = Tkinter.Tk()
MessFrame.geometry('800x400+200+200')
MessFrame.title('Main Frame')
Framelabel = Tkinter.Label(MessFrame, text='Text Here', fg= 'red')
Framelabel.place(x=10,y=10)
MessFrame.mainloop()
t1 = threading.Thread(target=create_frame)
t1.start()
#continue
print 1234
But...it's generally best to keep the GUI in the main thread.
This question already has an answer here:
Without exiting from the ssh_tunnel, open new terminal
(1 answer)
Closed 9 years ago.
My last question was also same thing, but did not get proper suggestion, so I am asking again.
I have a GUI which will connect to ssh. After it connects to ssh I am not able to do anything , so I have to open new terminal through script do rest of the operation (display respective outputs ) in that 'new terminal'.
Now I am able to open new window using subprocess but its not taking any action from GUI may be code issue. Please help me solve my problem.
I am using python and shell script for the backend and wxpython for GUI.
Note: I'm looking for solutions using Python and shell script.
My code is:
import time
import sys
import pexpect
c = pexpect.spawn("ssh -Y -L xxxx:localhost:xxxx user # host.com")
time.sleep(0.1)
c.expect("[pP]aasword")
c.sendline("xxxxxx")
sub = subprocess.call("xfce4-terminal")
if sub:
subprocess.call("svn update",shell=True)
time.sleep(0.2)
c.interact()
c.pexpect([user#host.com~]$)
# here after its connects to ssh then command wont be executed
c.sendline("xfce4-terminal")
In GUI I have a button "APPLY" and 5 radio button . I can select 1 radio button at a time and have to click button "APPLY". then it have connect to ssh tunnel and do the requested operation . Right now it is not allowing to do any of operation after it gets connect to ssh_tunnel.
The actual problem that you are seeing is how to avoid blocking the GUI event loop while you are running ssh.
There are two major approaches that allow to solve it:
run ssh in a background thread and use an appropriate for your GUI framework method of communicating with the main GUI thread to report results.
run ssh asynchronously and subscribe to its I/O events. Here's an example for gtk framework.
To run commands via ssh, you could try to use fabric as a library (it is higher level than paramiko).