Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7 用于在窗口上打印串行数据的python代码。_Python 2.7_Tkinter_Pyserial - Fatal编程技术网

Python 2.7 用于在窗口上打印串行数据的python代码。

Python 2.7 用于在窗口上打印串行数据的python代码。,python-2.7,tkinter,pyserial,Python 2.7,Tkinter,Pyserial,我对python和pyserial非常陌生。我的电脑安装了python 2.7.4和pyserial,我想在电脑上的一个单独窗口上打印串行接收的数据。首先必须打开窗口,然后在该窗口上打印串行数据。在这里,窗口必须打开一次,串行数据必须连续打印在窗口上,直到设备停止发送数据。 我试过使用这个代码,但它毫无价值。 请有人帮我查一下密码 import serial import Tkinter from Tkinter import * s = serial.Serial('COM10',9600)

我对python和pyserial非常陌生。我的电脑安装了python 2.7.4和pyserial,我想在电脑上的一个单独窗口上打印串行接收的数据。首先必须打开窗口,然后在该窗口上打印串行数据。在这里,窗口必须打开一次,串行数据必须连续打印在窗口上,直到设备停止发送数据。 我试过使用这个代码,但它毫无价值。 请有人帮我查一下密码

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()

这里的问题是有两个循环应该持续运行:GUI的主循环和传输串行数据的循环。要解决此问题,您可以启动一个新线程来接收串行端口的内容,将其放入一个队列中,并在GUI线程中定期检查此队列的内容:

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()
此代码使用我的Pi3 ttyS0串行端口以及串行连接的PC和从设备进行测试:
它100%使用串行连接的单个设备

您可以看看这个答案的第一部分。它展示了如何在tkinter循环中重复调用函数。这基本上是您想要做的,而不是在“True时”循环。非常感谢您的快速回答。我将尝试使用tkinter循环中的函数。串行对象是否提供了类似于api的队列,因此足以用作队列?换句话说,检查
inWaiting()
并直接从
process\u serial
循环读取是否足够?@FabienAndre问题不是从串行端口读取,而是同时运行两个循环。队列(与
after
方法结合使用)是在不冻结GUI的情况下通信两个线程的安全方式。我完全同意队列是处理两个线程的正确方式。我的问题是,在这种情况下,是否需要(以及为什么)使用第二个线程,而不是在循环后从Tkinter
读取串行数据。为了更加明确,为什么不直接替换
queue.qsize
check by
serial.inWaiting
queue.get
by
serial.read
?@FabienAndre您也可以这样做,但是信息会每隔100毫秒定期检索一次(这样,除了Tkinter主循环之外,您就没有任何循环了),而另一种方法是在发送内容的同时读取内容。现在我接收到的串行数据正在我的电脑屏幕上打印。