线程只执行一次……让我来猜一猜。
你可能会认为创建一个线程去执行某个动作就完事了?
一段代码不管是在主线程里还是在新建的线程里,它都是按代码本身的规则那么执行的,该循环就循环,该结束就结束。
所以,我们建立一个线程去执行某个动作,主要就是让这个动作的执行不影响主程的执行,不要因为它导致主程序的某环节等待这个动作的结果。
举例来说,一个定时3秒去读一下某个文件,总不能做个循环,读一下文件,然后sleep3秒吧,那除了这个,什么也干不了,基本都是在【等待3秒】这里耗着了。解决办法就是做个线程去完成【读某个文件】,然后这个事完了之后、前再建一个同样的线程让它三秒后执行。
看下图:
这个sort_loop就是这样干的:
【红框2】就是主要的工作内容(对self.data进行收缩)
如果简简单单的就这,那它就执行一次就完事了,哪怕你把sort_loop放到新线程里,也是一样。
要在sort_loop里再新建一个线程,新线程还是执行sort_loop,于是就是这样的:
A把桌子擦了擦,把抹布塞给了B;
B把桌子擦了擦,把抹布塞给了C
C把桌子擦了擦,把抹布塞给了D...
这才构成一个线程循环。
一、Pyqt5创建第一个窗体
很多人写窗体程序都是直接敲代码,不使用设计器,我个人不是很赞成这种做法。使用设计器的好处是直观、维护方便,尤其开发复杂窗体的效率高。
但是每次修改ui文件后,需要重新生成py文件,会将原来的内容覆盖掉,为了避免这种情况,引入了一个中间类。主要步骤如下:
1使用QtDesigner创建一个简单的对话框,保存成simpleDialog.ui。
2使用cmd,进入simpleDialog.ui文件所在的目录,运行命令pyuic5
simpleDialog.ui
>ui_simpleDialog.py
3打开ui_simpleDialog.py,pyqt自动生成的代码如下(无需任何修改):
from
PyQt5
import
QtCore,
QtGui,
QtWidgets
class
Ui_Form(object):#注意pyqt5窗体从object继承,不是QMainWindow了
def
setupUi(self,
Form):
Form.setObjectName("Form")
Form.resize(400,
300)
self.pushButton
=
QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(60,
70,
241,
131))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Form)
self.pushButton.clicked.connect(Form.close)
QtCore.QMetaObject.connectSlotsByName(Form)
def
retranslateUi(self,
Form):
_translate
=
QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form",
"Form"))
self.pushButton.setText(_translate("Form",
"PushButton"))
可以看到刚才新建的对话框的类名称是”Ui_Form”。
4新建一个simpleDialog.py文件,编写代码如下:
from
PyQt5
import
QtCore,
QtGui,
QtWidgets
from
ui_simpledialog
import
Ui_Form
import
sys
class
SimpleDialogForm(Ui_Form):#从自动生成的界面类继承
def
__init__(self,
parent
=
None):
super(SimpleDialogForm,
self).__init__()
def
yourFunctions(self):
Pass
#这个类中处理你自己的业务逻辑。界面ui可随心所欲的修改,不影响你已经编写的逻辑。
自定义一个类(SimpleDialogForm)继承自pyqt自动生成的类,然后覆写”构造函数”,剩余的工作就是你自己想要添加的功能了。
5完善运行测试代码,如下:
if
__name__
==
"__main__":
app
=
QtWidgets.QApplication(sys.argv)
main
=
QtWidgets.QMainWindow()#创建一个主窗体(必须要有一个主窗体)
content
=
SimpleDialogForm()#创建对话框
content.setupUi(main)#将对话框依附于主窗体
main.show()#主窗体显示
sys.exit(app.exec_())
6为什么要这么做?
基于界面与实现分离的原则,我们使用QtDesigner设计的窗体,仅仅作为界面使用,具体业务逻辑通过单独的文件实现,这样以后如果界面发生变动,pyqt自动生成窗体代码时不会覆盖掉我们已经编写的业务逻辑。
7推荐的做法:
为了有良好的封装性,将中间类修改为:
class
SimpleDialogForm(Ui_Form,
QtWidgets.QMainWindow):
def
__init__(self,
parent
=
None):
super(SimpleDialogForm,
self).__init__()
self.setupUi(self)#在此设置界面
#在此,可添加自定义的信号绑定
self.pushButton.clicked.connect(self.openFile)
self.pushButton_2.clicked.connect(self.closeApp)
测试代码这样写:
if
__name__
==
"__main__":
app
=
QtWidgets.QApplication(sys.argv)
main
=
SimpleDialogForm()
main.show()#在外面只需要调用simpleDialogForm显示就行,不需要关注内部如何实现了。
sys.exit(app.exec_())
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)