I am quite new to python and pyserial. My pc was installed with python 2.7.4 with pyserial and I want to print the serially received data on a seperate window on my pc. First the window has to be opened, then after the serial data should print on that window. Here the window has to be opened once and the serial data has to be continously print on the window until the device stops tramsmitting the data.
I tried with this code, but its worthless.
please someone help me with the code.
import serial
import Tkinter
from Tkinter import *
s = serial.Serial('COM10',9600) # open serial port
master = Tk()
master.geometry("1360x750") # a window pop up with width (1360) and height(750) which exatly fits my monitor screen..
while 1:
if s.inWaiting():
text = s.readline(s.inWaiting())
frameLabel = Frame( master, padx=40, pady =40)
frameLabel.pack()
w = Text( frameLabel, wrap='word', font="TimesNewRoman 37")
w.insert(12.0,text )
w.pack()
w.configure( bg=master.cget('bg'), relief='flat', state='Normal' )
mainloop()
The problem here is that you have two loops that should be constantly running: The mainloop for the GUI and the loop for transmitting the serial data. What you can do to solve this is to start a new thread to receive the content of the serial port, put it in a Queue, and check periodically in the GUI thread the content of this queue:
import serial
import threading
import time
import Queue
import Tkinter as tk
class SerialThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
s = serial.Serial('/dev/ttyS0',9600)
s.write(str.encode('*00T%'))
time.sleep(0.2)
while True:
if s.inWaiting():
text = s.readline(s.inWaiting())
self.queue.put(text)
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.geometry("1360x750")
frameLabel = tk.Frame(self, padx=40, pady =40)
self.text = tk.Text(frameLabel, wrap='word', font='TimesNewRoman 37',
bg=self.cget('bg'), relief='flat')
frameLabel.pack()
self.text.pack()
self.queue = Queue.Queue()
thread = SerialThread(self.queue)
thread.start()
self.process_serial()
def process_serial(self):
value=True
while self.queue.qsize():
try:
new=self.queue.get()
if value:
self.text.delete(1.0, 'end')
value=False
self.text.insert('end',new)
except Queue.Empty:
pass
self.after(100, self.process_serial)
app = App()
app.mainloop()
This code is tested with my Pi3 ttyS0 serial port and serially connected PC and slave device:
its 100% working with single device connected serially
Related
I'm working on numercial simulations in Abaqus 2020 and coded a GUI with Tkinter.
My problem is, that while running the Tkinter code everything works well unitl the start of the mainloop. Then both windows of Tkinter and Abaqus freeze. When I first close the Abaqus window, the Tkinter Window works correctly. I tried sth with threads but wihtout success..
Setup: Windows 10, Abaqus 2020, Python 2.7
here you find a minimal example:
import Tkinter as tk
from Tkinter import *
# Creating master Tkinter window
window = tk.Tk()
window.title('TKINTER-mini')
# window.attributes("-fullscreen", True)
width=1200
window.geometry("1800x1000")
# Frames
frame0 = Frame(window, width=width)
label_Titel = tk.Label(master=frame0, text ='Test', font=('Aerial 15 bold'))
label_Titel.grid(row=0, column = 0)
frame0.grid(row=0, column=2, padx=20, pady=20, ipadx = 20, ipady=20)
window.mainloop()
# window.update()
I'm looking forward to get some help. Thank you in advance!
Greets JBKingPile
I tried
#1
def __init__(self):
import threading
threading.Thread.__init__(self)
def shutdown_ttk_repeat(self):
self.mainroot.eval('::ttk::CancelRepeat')
self.mainroot.destroy()
def __init__(self, parent):
self.mainroot = parent
# self.mainroot.protocol("WM_DELETE_WINDOW", self.shutdown_ttk_repeat)
# self.tabpage()
self.root.after(1000, self.refresh())
self.root.mainloop()
#2
try:
# Tk will crash if pythonw.exe has an XP .manifest
# file and the root has is not destroyed explicitly.
# If the problem is ever fixed in Tk, the explicit
# destroy can go.
try:
gui = gui(window)
window.mainloop()
finally:
window.destroy()
except KeyboardInterrupt:
pass
#3
if __name__ == "__main__":
app = simpleapp_tk(window)
window.mainloop()
PyQt :Parent Window not waiting until child window closes. with reference to code shared below ,My welcome class object should wait till first_time class object completely finishes executing , but instead goes ahead and closes it self before first_time object finishes executing .
code :
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PySide.QtCore import QSettings
import sys
from PyQt4 import uic
#importing first configuration class
import configure as config_first
#loading initial settings
settings=QSettings('settings.ini',QSettings.IniFormat)
#loading the ui screens
form_class=uic.loadUiType("screens/firstscreen.ui")[0]
class welcome(QDialog,form_class):
#this signal is emitted when first configuration is done and ready to go
done_and_go_to_use = pyqtSignal()
def __init__(self):
super(welcome, self).__init__()
self.setupUi(self)
self.done_and_go_to_use.connect(self.close)
self.ready_btn.clicked.connect(self.ready)
def ready(self):
if_configured = settings.value('isConfigured', False)
if not if_configured :
first_time=config_first.configureFirst(self)
first_time.show()
self.close()
app = QApplication(sys.argv)
p = welcome()
p.show()
app.exec_()
below is the code for configure.py
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sqlite3
import csv
from PySide.QtCore import QSettings
from PyQt4 import uic
#loading initial settings
settings=QSettings('settings.ini',QSettings.IniFormat)
#loading ui screens
form_class=uic.loadUiType("screens/config_first.ui")[0]
#database connecting
con = sqlite3.connect("local.db")
cur = con.cursor()
cur.execute("CREATE TABLE if not exists marks (student_id int,student_name varchar(200));")
class configureFirst(QDialog,form_class):
done_configuring=pyqtSignal()
try_again=pyqtSignal()
def __init__(self,parent=None):
super(configureFirst, self).__init__(parent)
self.setupUi(self)
self.ok_btn.clicked.connect(self.ok_clicked)
self.cancel_btn.clicked.connect(self.cancel_clicked)
self.try_again.connect(self.ok_clicked)
self.done_configuring.connect(self.cancel_clicked)
self.show()
def ok_clicked(self):
file_select=QFileDialog.getOpenFileName(self,"open file","/")
if file_select:
with open(file_select, 'rb') as f:
reader = csv.reader(f)
ed = list(reader)
for row in ed:
if "name" not in row or "id" not in row:
cur.execute("Insert into marks Values (?,?);",(row[0],row[1]))
con.commit()
settings.setValue("isConfigured",True)
self.done_configuring.emit()
else:
#if recurssion is used the no of time it has to close increases and leads to integration problems
self.try_again.emit()
def cancel_clicked(self):
if_configured=settings.value("isConfigured")
if if_configured:
self.close()
else:
QMessageBox.critical(self,"PerfAnalyser","You Need to Configure For PerfAnalyser To Work")
def closeEvent(self,event):
#this method is triggered when 'X' is clicked i.e close button is clicked at the upper right corner
if_configured = settings.value("isConfigured")
if if_configured:
event.accept()
else:
QMessageBox.critical(self, "PerfAnalyser", "You Need to Configure For PerfAnalyser To Work")
event.ignore()
Thanks for the help in advance ...
I will try to help out since I notice few people have seen your post. I have had this happen a long time ago so I need a reminder, but I was unable to get your code running, I also tried to recreate your ui files and the screens directory but I was not successful. However, maybe the following is still useful.
In my working code, any time I needed to create a subwindow, I executed subwindows as follows from the main window's module:
dlg = SubWindowModuleName.StartSub()
dlg.exec_()
This will execute the subwindow and waits for it to close. Then, on the subwindow module (SubWindowModuleName in the above code, "configure" for you), I did this:
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(982, 521)
... # here I build the window (I noticed that you import UI files which is a much better way of doing this)
...
class StartSub(QtGui.QDialog, Ui_Dialog):
def __init__(self,parent=None):
QtGui.QDialog.__init__(self,parent)
self.setupUi(self)
I am trying to build a basic messaging system, but I have hit a major roadblock in the process. I can't get the window to close without it not responding and me having to close it in the Task Manager. From what I've read online, it sounds like I need to close when a sys.exit(0) to exit all the threads and connections. I have been stuck on this problem for days so I would really appreciate an answer and explanation to why it doesn't work! The meat of the problem is in the close_window() function. It is run able provided you have a basic server that accepts a connection. Thanks!
import wx
import socket
import threading
import sys
class oranges(wx.Frame):
def __init__(self,parent,id):
##Unimportant stuff
wx.Frame.__init__(self,parent,id," Retro Message",size=(500,500))
self.frame=wx.Panel(self)
self.input_box=wx.TextCtrl(self.frame, -1,pos=(15,350),size=(455,120),style=wx.NO_BORDER| wx.TE_MULTILINE)
self.messaging_box=wx.TextCtrl(self.frame, -1,pos=(15,15),size=(455,285),style=wx.NO_BORDER | wx.TE_MULTILINE|wx.TE_READONLY)
send_button=wx.Button(self.frame,label="Send",pos=(350,315),size=(75,40))
self.Bind(wx.EVT_BUTTON, self.sender,send_button)
self.Bind(wx.EVT_CLOSE, self.close_window)
self.counter = 1
self.socket_connect = socket.socket()
self.setup()
def sender(self,event):
self.socket_connect.send(self.input_box.GetValue())
self.input_box.Clear()
self.Refresh()
##Important stuff
def close_window(self,event): #This is the function in question#
self.counter = 0
self.socket_connect.shutdown(socket.SHUT_RDWR)
sys.exit(0)
def setup(self):
self.ip_enter = wx.TextEntryDialog(None, "Enter in the IP:", "Setup", "192.168.1.1")
if self.ip_enter.ShowModal() ==wx.ID_OK:
self.offical_ip = self.ip_enter.GetValue()
try:
self.socket_connect.connect((self.offical_ip,5003))
self.username = "false" #Tells the server just to give the user a IP username
self.Thread1 = threading.Thread(target = self.listening_connect)
self.Thread1.start()
except socket.error:
self.error_connect()
else:
sys.exit(0)
def listening_connect(self):
self.socket_connect.send(self.username)
while self.counter != 0:
data = self.socket_connect.recv(1024)
self.messaging_box.AppendText(data)
self.Refresh()
if not data:
break
self.socket_connect.close()
def error_connect(self):
pop_ups = wx.MessageDialog(None, "Failed to Connect to Server!", 'Error', wx.OK)
pop_ups.ShowModal()
self.setup()
if __name__=="__main__":
app=wx.App(False)
window=oranges(parent=None,id=-1)
window.Show()
app.MainLoop()
Here is a basic server program that should work with it(I am unable to test it but it is very similar to the real one)
import socket
HOST = '192.168.1.1'
PORT=5003
s = socket.socket()
s.bind((HOST, PORT))
s.listen(1)
c,addr = s.accept()
while True:
data = c.recv(1024)
if not data:
break
c.close()
You need to wait for the thread to end. Otherwise it's probably going to make the script hang. Why? Well the thread is separate from the GUI thread, so it doesn't get killed just because you closed down your wxPython application. Here is what I would recommend:
def close_window(self, event):
self.Thread1.join()
self.Destroy()
This makes the script wait for the thread to finish before closing the application. If you want the frame to disappear, then you should call self.Hide() before the join. Another method would be to put some logic in your thread where you can send it a message that tells it the application is shutting down, so the thread needs to abort.
You should probably check out the following Stack answer:
Is there any way to kill a Thread in Python?
Hi i am trying to disable a button , so that the command event does not work for some time .How can i make the button disabled for some time and then later reenable it , to get the callback function .
#! /usr/bin/python
from Tkinter import *
import Tkinter as tk
import time
class MyFrame(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.b1 = Button(self, text="Press Me!",command = self.callback)
self.count=0
self.but_flag=0
self.b1.grid()
def callback(self):
self.b1['state'] = DISABLED
for k in range(5):
time.sleep(1)
print k
self.b1['state'] = NORMAL
mainw = Tk()
mainw.f = MyFrame(mainw)
mainw.f.grid()
mainw.mainloop()
The problem is that the sleep in your callback function is blocking the UI from refreshing. Instead of using sleep, you could schedule the re-enabling of the button using after.
def callback(self):
self.b1['state'] = DISABLED
self.after(3000, self.enable)
def enable(self):
self.b1['state'] = NORMAL
But if you do any long-running task in callback, this will still freeze the UI.
Another alternative would be to create a worker thread for doing the actual work. This way, the UI thread is not blocked and the UI will be updated and the button deactivated/activated.
def callback(self):
threading.Thread(target=self.do_actual_work).start()
def do_actual_work(self):
self.b1['state'] = DISABLED
for i in range(5):
print i
time.sleep(1)
self.b1['state'] = NORMAL
Of course, you could also just add self.b1.update() after the disabling line to update the Button widget to its disabled state, but this will still leave the UI frozen until the method is finished.
This is my first try in building a gui and im trying to set up an irc client on ubuntu 14.04. Actually i got stuck when i tried to output the chat data in a textview on the gui but i think im missing something important here.
I was already able to send the chat data into the textview, when i put a while-loop into the button_clicked event. But then the whole gui of course hang up. So either the Chat read function reads only once or always. At least i tried to rearrange the structure around the Gtk.main() and it lead me to a "maximum recursion depth exceeded in cmp" error. it might have something to do with the setup of def init().
Maybe you could have a look at my code.
best regards,
yoshiwob
uimain.py
#!/usr/bin/python
from gi.repository import Gtk
import botmain
from botmain import connect, message, disconnect, read_chat, userlist
import os
class Gui:
def __init__(self):
Gtk.Builder().add_from_file("gladeui/uimain.glade")
Gtk.Builder().connect_signals(Gui())
window = Gtk.Builder().get_object("window1")
window.show_all()
def onDeleteWindow(self, *args):
Gtk.main_quit(*args)
def on_BTexit_clicked(self, button):
os._exit(0)
def on_BTconnect_clicked(self, button):
if button.get_label() == 'Connect':
button.set_label('Disonnect')
connected = True
connect()
# twitch_userlist()
else:
button.set_label('Connect')
disconnect()
connected = False
def on_BTsend_clicked(self, entry):
message(entry.get_text())
def main():
read_chat(builder)
Gtk.main_iteration_do(True)
if __name__ == "__main__":
Gui()
main();
botmain.py
import socket #imports module allowing connection to IRC
import threading #imports module allowing timing functions
from gi.repository import Gtk
from gnome_sudoku import gtk_goodies
import time
#sets variables for connection to twitch chat
bot_owner = 'deryoshiii'
nick = '-nick-'
channel = '#-nick-'
server = 'irc.twitch.tv'
password = '-oauth-'
irc = socket.socket()
queue = 13 #sets variable for anti-spam queue functionality
connected = False
def connect():
print("Connecting...")
irc.settimeout(300)
irc.connect((server, 6667)) #connects to the server
#sends variables for connection to twitch chat
irc.send('PASS ' + password + '\r\n')
irc.send('USER ' + nick + ' 0 * :' + bot_owner + '\r\n')
irc.send('NICK ' + nick + '\r\n')
irc.send('JOIN ' + channel + '\r\n')
print("Connected")
def userlist():
print('getting userlist...')
irc.send('WHO %s' % channel)
#http://www.qtcentre.org/threads/18292-Python-PyQt-IRC-Client
def disconnect():
irc.send('QUIT :')
# irc.shutdown(socket.SHUT_RDWR)
# irc.close()
def message(msg): #function for sending messages to the IRC chat
global queue
queue = 5
#print queue
if queue < 20: #ensures does not send >20 msgs per 30 seconds.
irc.send('PRIVMSG ' + channel + ' :' + msg + '\r\n')
else:
print('Message deleted')
def queuetimer(): #function for resetting the queue every 30 seconds
global queue
#print 'queue reset'
queue = 0
threading.Timer(30,queuetimer).start()
queuetimer()