python-3.x - PYQT 状态栏不更新
问题描述
我正在构建一个与 Arduino 通信的简单 QT UI。我实现了一个简单的设备自动检测机制。电脑正在寻找所有连接的串行设备并尝试向Hi!
可用端口发送消息。如果 Arduino 连接到电脑,它会回复此消息。我想在 UI 的状态栏上显示设备搜索过程的状态。但是,状态栏不会更新。它只显示最新消息。最初的想法甚至没有用于设备搜索的按钮。我只是在调用findDevice()
,setupUi()
但在这种情况下,UI 甚至直到findDevice()
执行结束才开始。如果我在 UI 设置期间直接调用该方法,我会看到一个白色窗口,并且在findDevice()
方法完成执行。那么为什么状态栏消息直到findDevice()
执行结束才更新,我该如何消除pushButton_Connect
?代码未完成。它有点长,但大部分是生成的代码。我只添加了几行。
编辑:这个问题的答案在这里:https ://stackoverflow.com/a/57500544/10370627 。另外我的closeEvent()
方法在下面的代码中不起作用。对于这个问题,解决方案在这里:https ://stackoverflow.com/a/22460392/10370627
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file C:\ard_serial\python_code\calibrator_ui.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
from pyqtgraph import PlotWidget
import numpy as np
import sys, time, serial, glob
# Global constants
ENCODING = "UTF-8"
GREETING = "Hi!"
DATA_READ = '0'
LIGHT_OFF = '1'
LED_ON = '2'
LASER_ON = '3'
EX_LED_ON = '4'
EX_LASER_ON = '5'
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# STARTS: User added class members
self.ser_port = None
# ENDS: User added class members
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1070, 595)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMinimumSize(QtCore.QSize(1070, 595))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.lineEdit_Input = QtWidgets.QLineEdit(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEdit_Input.sizePolicy().hasHeightForWidth())
self.lineEdit_Input.setSizePolicy(sizePolicy)
self.lineEdit_Input.setObjectName("lineEdit_Input")
self.gridLayout.addWidget(self.lineEdit_Input, 0, 1, 1, 1)
self.graphicsView_PlotWidget = PlotWidget(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.graphicsView_PlotWidget.sizePolicy().hasHeightForWidth())
self.graphicsView_PlotWidget.setSizePolicy(sizePolicy)
self.graphicsView_PlotWidget.setMinimumSize(QtCore.QSize(1050, 490))
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.NoBrush)
self.graphicsView_PlotWidget.setBackgroundBrush(QtGui.QColor('black'))
self.graphicsView_PlotWidget.setObjectName("graphicsView_PlotWidget")
self.gridLayout.addWidget(self.graphicsView_PlotWidget, 1, 0, 1, 5)
self.label_Only_integers = QtWidgets.QLabel(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_Only_integers.sizePolicy().hasHeightForWidth())
self.label_Only_integers.setSizePolicy(sizePolicy)
self.label_Only_integers.setObjectName("label_Only_integers")
self.gridLayout.addWidget(self.label_Only_integers, 0, 0, 1, 1)
self.pushButton_Generate = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_Generate.sizePolicy().hasHeightForWidth())
self.pushButton_Generate.setSizePolicy(sizePolicy)
self.pushButton_Generate.setObjectName("pushButton_Generate")
self.gridLayout.addWidget(self.pushButton_Generate, 0, 2, 1, 1)
self.pushButton_Connect = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_Connect.sizePolicy().hasHeightForWidth())
self.pushButton_Connect.setSizePolicy(sizePolicy)
self.pushButton_Connect.setObjectName("pushButton_Connect")
self.gridLayout.addWidget(self.pushButton_Connect, 0, 3, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1070, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# STARTS: User added setup code
self.pushButton_Generate.clicked.connect(lambda:self.draw())
'''
I even do not want to use a push button for device search. But when I
call findDevice() method the UI appears after the execution of
findDevice() method.
'''
self.pushButton_Connect.clicked.connect(lambda:self.findDevice())
x = np.random.normal(size = 500)
y = np.random.normal(size = (3, 500))
for i in range(3):
self.graphicsView_PlotWidget.plot(x, y[i], pen = (i, 3))
# ENDS: User added setup code
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Calibrator"))
self.label_Only_integers.setText(_translate("MainWindow", "Only integers"))
self.pushButton_Generate.setText(_translate("MainWindow", "Generate"))
self.pushButton_Connect.setText(_translate("MainWindow", "Connect"))
# STARTS: User added methods
def findDevice(self):
'''
Here I expect to see all the status bar messages but I see only the last
one. For instance if there is no serial device is connected, I only see
<No serial device is connected> message on the status bar.
'''
self.statusbar.showMessage("Looking for device...")
print("Looking for device...")
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
import subprocess
# ports = glob.glob('/dev/tty[A-Za-z]*')
ports = glob.glob('/dev/ttyUSB[0-9]*')
for port in ports:
process = subprocess.Popen(["sudo", "chmod", "777", port], stdout = subprocess.PIPE)
output, error = process.communicate()
else:
raise EnvironmentError('Unsupported platform')
for port in ports:
try:
self.ser_port = serial.Serial(port, 115200)
time.sleep(1.8)
self.statusbar.showMessage("Trying: " + str(port))
print("Trying:", port)
self.ser_port.write(GREETING.encode(ENCODING))
time.sleep(0.1)
self.ser_port.reset_input_buffer()
time.sleep(1)
read_data = self.ser_port.read_all().decode(ENCODING)
if(GREETING == read_data):
self.statusbar.showMessage("Device detected on: " + str(port))
print("\nDevice detected on:", port)
else:
self.statusbar.showMessage("No device detected")
print("No device detected")
except (OSError, serial.SerialException):
pass
if(self.ser_port is None):
print("No serial device is connected")
self.statusbar.showMessage("No serial device is connected")
def draw(self):
self.graphicsView_PlotWidget.clear()
def closeEvent(self, event):
self.ledit.setText(LIGHT_OFF)
if(self.ser_port is not None):
ret_val = self.ser_port.close()
print("Program terminated with return code: ", ret_val)
# ENDS: User added methods
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
解决方案
推荐阅读
- html - 调整页面大小时,文本消失但容器仍然存在
- jsp - 如何使用从BeanClass返回的对象数组并在JSP的DropDown中显示?
- r - 循环遍历三个数据帧列表 R
- javascript - 获取印度当前时间和日期
- javascript - 在 Node/Express 中解压缩嵌套文件
- docker - 保存现有的 Docker 堆栈以重新应用它
- scala - 根据 Map 类型列的大小将 Spark DataFrame 行分成多行
- php - 如何使用 PHP 和 str_replace 显示 mysql 表中的所有字段
- java - 如何用不同的继承人反序列化 JSON
- c# - 如何调整 Unity 2D 跳跃速度?