![Qt for Python PySide6 GUI界面开发详解与实例](https://wfqqreader-1252317822.image.myqcloud.com/cover/296/47216296/b_47216296.jpg)
1.3 PySide6可视化编程架构
上一节介绍了创建窗口和在窗口上创建控件的方法,这个方法将创建窗口和创建窗口控件的代码与控件的事件代码放到同一段程序中,如果程序非常复杂,控件很多,事件也很多,势必造成代码混杂,程序可读性差,编程效率也不高。为此可以把创建窗口控件的代码放到一个函数或类中,创建窗口的代码放到主程序中,从而使程序的可读性得到提高,也提高了编程效率。
1.3.1 界面用函数来定义
下面的代码将创建窗口控件的代码放到函数setupUi()中,按钮事件与窗口事件的关联也移到函数中。setupUi()函数的形参是窗口,在主程序中调用setupUi()函数,并把窗口实例作为实参传递给setupUi()函数,在setupUi()函数中往窗口上创建控件,运行程序得到与上一节相同的窗口。
![](https://epubservercos.yuewen.com/020B52/26580911501198806/epubprivate/OEBPS/Images/Figure-P25_67743.jpg?sign=1738758850-0dgZcS0hJEIINQSnGScRfECt1324IQN7-0-4b4293de0e1c86ef331c57af58d9a18d)
1.3.2 界面用类来定义
下面的程序将创建窗口控件的代码定义到MyUi类的setupUi()函数中,各个控件是MyUi类中的属性,在主程序中用MyUi类实例化对象ui,这样在主程序中就可以用ui引用窗口上的任何控件,在主程序中通过ui就可以修改控件的参数。例如主程序中用ui.button.setText("Close")语句修改了按钮的显示文字,按钮事件与窗口事件的关联也移到了主程序中,当然也可以在类的函数中实现。
![](https://epubservercos.yuewen.com/020B52/26580911501198806/epubprivate/OEBPS/Images/Figure-P25_67744.jpg?sign=1738758850-nFSP5cRxYLD2LmyaqwNf2jhCZdgEt9qs-0-fb7f13aef2267d56ab7fa1c851a4e30b)
1.3.3 界面用模块来定义
如果一个界面非常复杂,创建界面控件的代码也就会很多,如果使用模块和包的概念,则程序中创建界面控件的类MyUi可以单独存放到一个文件中,在使用的时候用import语句把MyUi类导入进来,实现控件代码与窗口代码的分离。
下面是在窗口上创建控件的代码,然后把代码保存到Python可以搜索到的路径下的myUi.py文件中。
![](https://epubservercos.yuewen.com/020B52/26580911501198806/epubprivate/OEBPS/Images/Figure-P26_67746.jpg?sign=1738758850-z47YbEhHkEhOOXxeHUNnIqYOTqPf74Pp-0-216a38cfa24b7f62b3cb6b31d0cca7c2)
新建一个py文件,在这个py文件中输入如下所示的代码,在第3行中用from myUi import MyUi语句把MyUi类导入进来,在主程序中用ui=MyUi()语句创建MyUi类的实例对象ui,然后就可以用ui引用myUi.py文件中定义的控件。
import sys#Demo1_8.py from PySide6.QtWidgets import QApplication,QWidget from myUi importMyUi #导入myUi.py文件中的MyUi类 if__name__=="__main__": app=QApplication(sys.argv) myWindow=QWidget() ui=MyUi() #用MyUi类创建实例ui ui.setupUi(myWindow) #调用ui的方法setupUi(),并以窗口实例作为实参 ui.button.setText("Close") #重新设置按钮上显示的文字 ui.button.clicked.connect(myWindow.close) #窗口上的按钮事件与窗口事件关联 myWindow.show() sys.exit(app.exec())
1.3.4 界面与逻辑的分离
上例的代码中,可以把创建窗口和对控件操作的代码单独放到一个函数或类中,含有控件的代码称为界面代码,实现控件动作的代码称为逻辑或业务代码。
下面的代码创建myWidget()函数,在函数中用widget=QWidget(parent)语句创建QWidget类的实例对象widget,这时首先执行的是QWidget类的初始化函数__init__(),经过初始化后的对象成为真正窗口,注意myWidget()函数的返回值是窗口实例对象widget。在主程序中调用myWidget()函数,得到返回值,然后显示窗口并进入消息循环。
![](https://epubservercos.yuewen.com/020B52/26580911501198806/epubprivate/OEBPS/Images/Figure-P27_67748.jpg?sign=1738758850-QbgC9YgXpDs0QAMiZGsZykKHuYxtB4Vh-0-b525486322f9eac99e66d99779e98247)
上面代码中,只是用一个函数将界面与逻辑或业务分离,如果要对界面进行多种操作或运算,显然只用一个函数来定义是不够的。由于在类中可以定义多个函数,因而如果用类来代替上述函数,就可以极大地提高编程效率。为此可以把创建窗口和对控件操作的代码放到一个类中。
下面的代码创建一个类MyWidget,其父类是窗口类QWidget,在初始化函数__init__()中用super()函数调用父类的初始化函数,这时类MyWidget中的self将会是窗口类QWidget的实例对象,也就是一个窗口。在主程序中用类MyWidget实例化对象myWindow,myWindow就是MyWidget的self的具体值。myWindow可以显示出来,也可以进入事件循环。
![](https://epubservercos.yuewen.com/020B52/26580911501198806/epubprivate/OEBPS/Images/Figure-P28_67749.jpg?sign=1738758850-t0hDSImiAay32J9Y79PvC4D8ptnkzvoy-0-49c2acc263aa12406a3aec04e71bb5e6)
上面的程序属于单继承的方法,自定义类MyWidget只继承了QWidget类,在类MyWidget中还要定义类MyUi的实例对象。下面介绍多继承的方法,自定义类MyWidget同时继承QWidget类和MyUi类,多继承无须再定义类MyUi的实例对象,类中的self既指QWidget类的窗口对象,也指MyUi的实例对象,即窗口上的控件。多继承方法的优点是访问控件方便,缺点是过于开放,不符合面向对象编程的封装要求,如果界面的属性和逻辑函数的属性都较多时,不便于区分是哪个类中定义的属性和方法。本书以单继承的方式讲解PySide6的可视化编程。
![](https://epubservercos.yuewen.com/020B52/26580911501198806/epubprivate/OEBPS/Images/Figure-P28_67750.jpg?sign=1738758850-TV2XuQHOR9JEfeesYLaTQ246joG9tCb1-0-299b5fb4887f61ae36d3a556550c04c7)
如果窗口上的控件不是太多,也可以把创建控件的函数直接放到窗口类中,在窗口类的初始化函数中调用该函数,例如下面的代码。
![](https://epubservercos.yuewen.com/020B52/26580911501198806/epubprivate/OEBPS/Images/Figure-P29_67751.jpg?sign=1738758850-CXjaeya7ly05Zb7SPgmZIxz8TXtY6BfI-0-a51cae28bdb6afbbbaed1bceaf75a7cf)
以上几种方法的运行结果完全相同,请读者仔细体会这种界面与逻辑分离的编程架构模式。