我在开始使用pyqt5编程GUI之前做了一些初步测试,今天我发现了一些我无法解决的问题。
我的代码如下:
from PyQt5 import QtCore, QtGui, QtWidgets
import time
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(398, 398)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(30, 40, 131, 61))
self.lineEdit.setText("")
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(30, 120, 131, 61))
self.lineEdit_2.setText("")
self.lineEdit_2.setObjectName("lineEdit_2")
self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber.setGeometry(QtCore.QRect(180, 40, 64, 23))
self.lcdNumber.setObjectName("lcdNumber")
self.lcdNumber_2 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_2.setGeometry(QtCore.QRect(180, 120, 64, 23))
self.lcdNumber_2.setObjectName("lcdNumber_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 398, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.number = 0
self.number_2 = 0
self.lcdNumber.display(self.number)
self.lcdNumber_2.display(self.number_2)
self.lineEdit.returnPressed.connect(self.change_number)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
def change_number(self):
ip = int(self.lineEdit.text())
if ip > self.number:
count = 1
elif ip < self.number:
count = -1
else:
count = 0
while self.number != ip :
self.number += count
self.lcdNumber.display(self.number)
time.sleep(1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
如您所见,我有两个QLineEdit框和两个QLCDNumber,用于显示我在相应QLineEdit中写的数字。
问题1
我可以使用以下代码在QLCDNumber中显示数字:
self.lineEdit.returnPressed.connect(self.change_number)
...
def change_number(self):
self.lcdNumber.display(int(self.lineEdit.text()))
但是,如果我想以一定的时间延迟逐个更改显示的数字,我的代码并不像我期望的那样工作。
例如,如果当前数字为0并且我在QLineEdit中键入10,则程序冻结10秒,然后数字10显示在QLCDNumber上,而我希望它会逐秒更新。我真的无法弄清楚问题出在哪里。
问题2
我有两个QLineEdit和两个QLCDNumber,写两个不同的函数change_number没有多大意义。 但是,我找不到一种编写通用函数的方法,该函数将作为QLCDNumber将被更新的输入以及哪个QLineEdit将作为输入。 在伪代码中,它将是这样的:
self.LINEEDIT_NAME.returnPressed.connect(self.change_number(LINEEDIT_NAME,QLCD_NAME))
...
def change_number(self,LINEEDIT_NAME,QLCD_NAME):
ip = int(self.LINEEDIT_NAME.text())
if ip > self.number:
count = 1
elif ip < self.number:
count = -1
else:
count = 0
while self.number != ip :
self.number += count
self.QLCD_NAME.display(self.number)
time.sleep(1)
但我无法将LINEEDIT_NAME和QLCD_NAME用作功能的变量。
答案 0 :(得分:0)
time.sleep()
是阻止PyQt
循环的任务,因此不建议使用它,可以使用QTimer
轻松替换该任务。
为方便工作,我们将创建一个继承自QLCDNumber
并使用QTimer
更新值的类
<强> TimerLCDNumber.py 强>
from PyQt5 import QtCore, QtGui, QtWidgets
class TimerLCDNumber(QtWidgets.QLCDNumber):
def __init__(self, *args, **kwargs):
QtWidgets.QLCDNumber.__init__(self, *args, **kwargs)
self.timer = QtCore.QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.onTimeout)
self.finished = self.value()
def setValue(self, value):
self.finished = value
self.timer.start()
def onTimeout(self):
current = self.value()
if self.finished != current:
count = 1 if self.finished > current else -1
self.display(current + count)
else:
self.timer.stop()
可以通过Qt Designer推广此任务,或者只需更改,假设Qt Designer生成的文件名为design.py:
<强> design.py 强>
self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_2 = QtWidgets.QLCDNumber(self.centralwidget)
为:
self.lcdNumber = TimerLCDNumber(self.centralwidget)
self.lcdNumber_2 = TimerLCDNumber(self.centralwidget)
此外,必须导入TimerLCDNumber
类:
from TimerLCDNumber import TimerLCDNumber
建议将设计与逻辑分开,以便创建一个名为main.py的新文件,用于导入设计类并实现逻辑:
<强> main.py 强>
from PyQt5 import QtCore, QtGui, QtWidgets
from design import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
self.lineEdit.returnPressed.connect(lambda: self.lcdNumber.setValue(int(self.lineEdit.text())))
self.lineEdit_2.returnPressed.connect(lambda: self.lcdNumber_2.setValue(int(self.lineEdit_2.text())))
self.lcdNumber.display(0)
self.lcdNumber_2.display(0)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
在我们文件夹的最后,我们必须具有以下结构:
.
├── design.py
├── main.py
└── TimerLCDNumber.py
第二个问题的可能解决方案是使用lambda函数:
第一个选项:
self.lineEdit.returnPressed.connect(lambda: self.lcdNumber.setValue(int(self.lineEdit.text())))
self.lineEdit_2.returnPressed.connect(lambda: self.lcdNumber_2.setValue(int(self.lineEdit_2.text())))
第二个选项:
self.lineEdit.returnPressed.connect(lambda: change_number(self.lineEdit, self.lcdNumber))
self.lineEdit_2.returnPressed.connect(lambda: change_number(self.lineEdit_2, self.lcdNumber_2))
def change_number(self,LINEEDIT_NAME,QLCD_NAME):
QLCD_NAME.setValue(int(LINEEDIT_NAME.text()))
可以在以下link找到完整的代码。