我使用pyside6的QT Designer制作了图形界面,并且转换成了py文件,在主程序中使用“类”可以正常工作,但我不想把整个程序都写到这一个类里面,如果写外部函数又调用不了类里面的按钮,文本框等(比如禁用按钮,设置文本显示)。
我的问题是:
1如何不使用“类”来实现 按钮连接函数 和 窗口的正常显示与工作,请给出简明的示例代码。
2如果用“类”,那么如何用外部函数来设置按钮禁用和文本内容显示,请给出简明示例代码。
3主程序中的self.setupUi(self)是什么意思?(为什么要写这句)
十分感谢!
主程序
class Widget(QWidget, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
self.tsb.clicked.connect(self.testspeed)
def speed(self):
self.cs.setText("测速中")
self.cs.setEnabled(False)
self.info.setText('测速中。。。')
self.sccs_thread = Thread(target=self.sccs) # 建立线程实例
self.sccs_thread.start() # 开启线程
界面文件
class Ui_Form(object):
def setupUi(self, Form):
if not Form.objectName():
Form.setObjectName(u"Form")
Form.resize(989, 997)
#测速按钮
self.tsb = QPushButton(Form)
self.tsb.setObjectName(u"cs")
self.tsb.setFont(font)
#信息显示窗口
self.info = QTextBrowser(Form)
self.info.setObjectName(u"info")
self.info.setFont(font)
类实例化以后,不论你怎么都可以调用类的控件,函数里面你可以传参啊
如果不使用类,ui还是一个类,实例化以后,直接调用就行。
面向对象编程,代码多了,最好是分文件的。所以最后实际上很少会再单独写一个函数去调用主界面的控件,都是写成类的形式。
self.setupUi(self)就是对界面初始化
单独Ui文件(ui_form.py)
class Ui_Widget(object):
def setupUi(self, Widget):
if not Widget.objectName():
Widget.setObjectName(u"Widget")
Widget.resize(800, 600)
self.frame = QFrame(Widget)
self.frame.setObjectName(u"frame")
self.frame.setGeometry(QRect(80, 100, 641, 351))
self.frame.setFrameShape(QFrame.StyledPanel)
self.frame.setFrameShadow(QFrame.Raised)
self.tsb = QPushButton(self.frame)
self.tsb.setObjectName(u"tsb")
self.tsb.setGeometry(QRect(60, 40, 82, 28))
self.info = QTextBrowser(self.frame)
self.info.setObjectName(u"info")
self.info.setGeometry(QRect(200, 40, 256, 192))
self.retranslateUi(Widget)
QMetaObject.connectSlotsByName(Widget)
# setupUi
def retranslateUi(self, Widget):
Widget.setWindowTitle(QCoreApplication.translate("Widget", u"Widget", None))
self.tsb.setText(QCoreApplication.translate("Widget", u"PushButton", None))
主程序
# This Python file uses the following encoding: utf-8
import sys
import time
from PySide6.QtWidgets import QApplication, QWidget,QHBoxLayout
from PySide6.QtCore import QThread
from thread import TestSpeed
# Important:
# You need to run the following command to generate the ui_form.py file
# pyside6-uic form.ui -o ui_form.py, or
# pyside2-uic form.ui -o ui_form.py
from ui_form import Ui_Widget
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_Widget()
self.ui.setupUi(self)
main_layout=QHBoxLayout()
self.ui.frame.setLayout(main_layout)
main_layout.addWidget(self.ui.tsb)
main_layout.addWidget(self.ui.info)
self.ui.tsb.setText("测速")
self.ui.tsb.clicked.connect(self.speed)
#线程初始化,子线程完成测试后,发信号给主界面。
self.thread = QThread()
self.test_thread=TestSpeed(self)
self.test_thread.moveToThread(self.thread)
self.test_thread._signal.connect(self.reflash)
def speed(self):
self.ui.tsb.setEnabled(False)
self.ui.info.setText('测速中。。。')
self.test_thread.start()
def reflash(self):
self.ui.info.setText('测速完毕')
self.ui.tsb.setEnabled(True)
def setText(Widget):
Widget.ui.info.setText("准备测速")
Widget.ui.tsb.setEnabled(True)
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = Widget()
setText(widget)
widget.show()
sys.exit(app.exec())
子线程:(thread.py)
from PySide6.QtCore import Signal,QThread
import time
#import datetime
class TestSpeed(QThread):
# 通过类成员对象定义信号对象
_signal = Signal()
def __init__(self,parent):
super(TestSpeed, self).__init__()
self.parent=parent
def __del__(self):
self.wait()
def run(self):
time.sleep(1)
for i in range(3):
self.parent.ui.info.append(f"{i+1}秒")
time.sleep(1)
self._signal.emit()
最终效果:
如果不使用类,可以在主程序中直接实例化界面文件中的组件,并连接信号和槽。示例代码如下:
def testspeed():
print("测速中")
if __name__ == '__main__':
app = QApplication(sys.argv)
form = Ui_Form()
form.tsb.clicked.connect(testspeed)
form.show()
sys.exit(app.exec_())
如果使用类,可以在外部函数中传入类的实例,通过实例访问类中的组件。示例代码如下:
class Widget(QWidget, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
self.tsb.clicked.connect(self.testspeed)
def disable_button(widget):
widget.tsb.setEnabled(False)
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = Widget()
disable_button(widget)
widget.show()
sys.exit(app.exec_())
self.setupUi(self) 是将界面文件中定义的组件和布局应用到类的实例上,使得类的实例可以显示界面并对组件进行操作。
通常来说,可以在主程序中实例化图形界面的类,通过信号与槽的连接实现界面交互。
可以参考以下例程及博客:Python 小白从零开始 PyQt5 项目实战(8)汇总篇(完整例程)
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import uiDemo3 # 导入图像界面设计文件
if __name__ == '__main__':
app = QApplication(sys.argv) # 创建应用程序对象
MainWindow = QMainWindow() # 创建主窗口
ui = uiDemo3.Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show() # 显示主窗口
sys.exit(app.exec_()) # 在主线程中退出