093.PyQt5_QTDesigner_具体使用

2023-10-13 17:59

本文主要是介绍093.PyQt5_QTDesigner_具体使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈

QTDesigner 具体使用

  • QtDesigner界面
    • 工具界面包含
    • 1、菜单栏
    • 2、工具栏
    • 3、控件盒子
    • 4、控件列表
    • 5、属性面板
    • 6、信号与槽、动作、资源面板
  • 控件操作
    • 添加控件:直接从左侧控件盒子中拖到窗体中
    • 控件是按功能或者布局分组
      Layoutts                        # 布局控件
      Spacers                         # 弹簧控件
      Buttons                         # 按钮控件
      Item Views(Model-Based)         # 
      Item Widgets(Item-Based)        # 
      Containers                      # 容器控件
      Input Widgets                   # 输入控件
      Display Widgets                 # 展示控件
      
    • 控件属性在右侧属性面板,可以直接搜索
    • 常用属性,在鼠标右键菜单中
    • 右侧属性面板搜索栏后面的“+”,可以给控件添加动态属性, setProperty(属性名,属性值)
  • 样式表和资源使用
    • 在控件属性面板直接搜索stylesheet —— 点击属性后面的...
    • 在控件上鼠标右键 —— Change styleSheet...(改变样式表)
    • 编辑样式表,可以直接添加资源、渐变色、颜色(前景、背景、边框)、字体等
    • 界面如下
    • 添加资源一般都是操作图片资源(背景图片、边框图片、前景图片)
    • ui文件并不能直接通过文件路径使用本地文件,必须通过资源管理文件的名称列表和资源路径列表进行关联使用
    • 后期,我们将资源管理文件(.qrc)转换成py文件,py文件就包含了qrc文件代码和资源文件(资源文件以二进制的方式保存在py文件中)
  • 控件类型提升(自定义类使用)
  • 首先我们写一个自定义类Btn继承自QPushbutton
    # 创建一个MyBtn.py文件,代码如下from PyQt5.Qt import *class Btn(QPushButton):def __init__(self, *args, **kwargs):super(Btn, self).__init__(*args, **kwargs)print('自定义按钮类')
    
  • 在QtDesigner中使用这个自定义类
    • 1、在窗体中添加一个该自定义类的父类控件
    • 2、鼠标右击该控件 —— Promote to...(提升为...)
    • 3、填写好要提升为那种类,该类所在的模块名(py文件名,这里注意不要写文件后缀),点击Add(添加)
    • 4、选中添加的 提升的类,点击 Promote(提升)
    • 5、提升完了之后,他们直接Ctrl+R运行,并没有看到任何效果
    • 6、此时,我们需要将ui文件转换为py文件,再直接运行py文件就能看到效果了(转换后的py文件如下)
      # -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'test.ui'
      #
      # Created by: PyQt5 UI code generator 5.15.9
      #
      # WARNING: Any manual changes made to this file will be lost when pyuic5 is
      # run again.  Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(400, 300)Form.setStyleSheet("")self.pushButton = Btn(Form)self.pushButton.setGeometry(QtCore.QRect(100, 70, 121, 91))self.pushButton.setObjectName("pushButton")self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.pushButton.setText(_translate("Form", "PushButton"))
      from MyBtn import Btnif __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QWidget()ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())
    • 其中有两句代码说明了这个按钮已经提升为我们自定义的类了
    • 7、自定义类添加信号与槽函数:回到QtDesigner工具,切换到信号与槽编辑模式
    • 8、 信号与槽添加完成之后,我们需要重新将ui文件转换为py文件,然后在py文件中编写具体的槽函数内容
      # -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'test.ui'
      #
      # Created by: PyQt5 UI code generator 5.15.9
      #
      # WARNING: Any manual changes made to this file will be lost when pyuic5 is
      # run again.  Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(412, 300)Form.setStyleSheet("")self.pushButton = Btn(Form)self.pushButton.setGeometry(QtCore.QRect(100, 70, 121, 91))self.pushButton.setObjectName("pushButton")self.retranslateUi(Form)self.pushButton.clicked.connect(Form.btn_click) # type: ignoreQtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.pushButton.setText(_translate("Form", "PushButton"))
      from MyBtn import Btnif __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QWidget()Form.btn_click = lambda :print('自定义按钮被点击了')ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())
  • 布局管理器使用
    • 窗体中有控件未设置布局时,右侧对象查看器中窗体对象会显示打破布局标志
    • 窗体中控件全部设置布局后,右侧对象查看器中窗体对象打破布局标志会消失
    • 为整个窗体设置布局
      • 1、在窗体界面选中窗体或者点击右侧对象查看器中的窗体
      • 2、点击工具栏上相应的布局按钮或者鼠标右键 —— 布局(lay out) —— 选择相应布局
    • 为多个控件设置布局
      • 1、在窗体界面框选选中多个控件或者右侧对象查看器中通过shift或ctrl键选中需要布局的多个控件
      • 2、点击工具栏上相应的布局按钮或者鼠标右键 —— 布局(lay out) —— 选择相应布局
    • 取消布局
      • 1、在窗体界面选中已布局的控件或者右侧对象查看器中选中已布局的控件
      • 2、点击工具栏上打破布局按钮或者鼠标右键 —— 布局(lay out) —— 打破布局
    • sizePolicy属性设置策略和拉伸系数
      Horizontal Policy       # 垂直策略
      Vertical Policy         # 水平策略
      # 策略参数Fixed               # 固定尺寸Minimum             # 最小尺寸Maximum             # 最大尺寸Preferred           # 优先分配空间MinimumEXpanding    # EXpanding           # 尽可能占据更多空间LgnoredHorizontal Stretch      # 垂直拉伸系数
      Vertical Stretch        # 水平拉伸系数
      
    • 通过minimumSize和MaximunSize设置为相同值来固定控件的尺寸(相当于fixedSize)
  • ui文件使用
    • 方法一:直接调用ui文件
      • 直接调用ui文件需要导入模块
        from PyQt5.uic import loadUi
        
      • 加载ui文件语法
        loadUi(ui文件名, self)
        
      • 示例(创建一个test_login.py文件)
        from PyQt5.Qt import *
        import sysclass Window(QWidget):def __init__(self):super().__init__()self.setWindowTitle('ui文件使用')self.resize(500, 300)self.addWidget()def addWidget(self):from PyQt5.uic import loadUiloadUi('login.ui', self)if __name__ == '__main__':app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())
      • 通过直接加载ui文件的方式可以直接运行,但是经常会出现一些奇奇怪怪的问题,比如资源图片加载不成功,信号与槽函数连接报错等
      • 我们可以通过ui文件转换后的py文件来分析一下
      • 图中可以看出来,其实ui文件就是自定义了一个类Ui_Form,继承自object
      • 在该自定义类中,通过setupUi方法将所有的控件都赋值给了这个类的各个属性
      • setupUi方法有一个形参Form,并且在创建所有控件的时候,将Form设置为了所有控件的父对象
      • 那么,通过loadUi方法读取ui文件时,将self作为实参传递进去(这里的self,是test_login.py文件中的window对象)
      • 相当于ui文件中的所有Form即为window对象(也就是说window是所有子控件的父对象)
      • 我们可以在test_login.py文件中,通过self.children()来看一下window对象有哪些子控件
      • 也可以通过dir(self)来获取window对象内部有哪些属性可以使用(可以通过这些属性来获取到子控件对象)
      • 这里dir函数实际是获取到如图中红色框选部分的属性,然后再通过这些属性获取到子控件对象
      • 拿到了子控件对象,那就可以对子控件进行一系列的操作了,比如连接信号与槽,获取子控件内容等...
        from PyQt5.Qt import *
        import sysclass Window(QWidget):def __init__(self):super().__init__()self.setWindowTitle('ui文件使用')self.resize(500, 300)self.addWidget()def addWidget(self):from PyQt5.uic import loadUiloadUi('login.ui', self)# print(self.children())# print(dir(self))self.btn_login.clicked.connect(self.btn_click)def btn_click(self):account = self.le_username.text()password = self.le_password.text()print(account, password)if __name__ == '__main__':app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())
      • 方法一在后期很少使用,所以了解即可。后期主要还是使用方法二
    • 方法二:将ui文件转换成py文件后再加载
      • 1、通过pyuic5工具将ui文件转换成py文件
      • 2、根据生成的py文件,创建另外一个py文件进行加载
      • 3、对ui文件中使用的资源进行处理,通过pyrcc5工具将qrc文件转换成py文件
      • 4、补全槽函数,给ui文件中使用到的槽函数写具体的执行过程
      • 注意:后期我们不要修改界面文件(ui文件转换的py文件),而是通过新建一个py文件去加载这个界面文件
      • 因为我们的界面需要改变的时候,修改ui文件之后,再次转换成py文件会讲之前的py文件全部覆盖,手动修改的内容将全部丢失
      • 我们的设计要做到界面与逻辑分离
      • A、创建py文件,以包的模式加载界面文件,通过包里面的类创建对象
        • ui文件转py文件(login.py)
        # login.py 文件# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'login.ui'
        #
        # Created by: PyQt5 UI code generator 5.15.9
        #
        # WARNING: Any manual changes made to this file will be lost when pyuic5 is
        # run again.  Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(395, 186)Form.setStyleSheet("")self.verticalLayout = QtWidgets.QVBoxLayout(Form)self.verticalLayout.setContentsMargins(0, 0, 0, 8)self.verticalLayout.setSpacing(6)self.verticalLayout.setObjectName("verticalLayout")self.widget = QtWidgets.QWidget(Form)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())self.widget.setSizePolicy(sizePolicy)self.widget.setStyleSheet("background-image: url(:/back/images/3.jpg);")self.widget.setObjectName("widget")self.verticalLayout.addWidget(self.widget)self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout.addItem(spacerItem)self.label_1 = QtWidgets.QLabel(Form)self.label_1.setObjectName("label_1")self.horizontalLayout.addWidget(self.label_1)self.le_username = QtWidgets.QLineEdit(Form)self.le_username.setObjectName("le_username")self.horizontalLayout.addWidget(self.le_username)spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout.addItem(spacerItem1)self.verticalLayout.addLayout(self.horizontalLayout)self.horizontalLayout_2 = QtWidgets.QHBoxLayout()self.horizontalLayout_2.setObjectName("horizontalLayout_2")spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem2)self.label_2 = QtWidgets.QLabel(Form)self.label_2.setObjectName("label_2")self.horizontalLayout_2.addWidget(self.label_2)self.le_password = QtWidgets.QLineEdit(Form)self.le_password.setObjectName("le_password")self.horizontalLayout_2.addWidget(self.le_password)spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem3)self.verticalLayout.addLayout(self.horizontalLayout_2)self.btn_login = QtWidgets.QPushButton(Form)self.btn_login.setMinimumSize(QtCore.QSize(270, 30))self.btn_login.setMaximumSize(QtCore.QSize(270, 30))self.btn_login.setStyleSheet("")self.btn_login.setObjectName("btn_login")self.verticalLayout.addWidget(self.btn_login, 0, QtCore.Qt.AlignHCenter)self.widget.raise_()self.btn_login.raise_()self.label_1.setBuddy(self.le_username)self.label_2.setBuddy(self.le_password)self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.label_1.setText(_translate("Form", "账号(&N):"))self.label_2.setText(_translate("Form", "密码(&P):"))self.btn_login.setText(_translate("Form", "登录"))
        import backgroud_rcif __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QWidget()ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())
        • qrc文件转py文件(background_rc.py)
        # 二进制文件太长,此处省略
        
        • 创建py文件加载界面文件(load_login.py)
        from PyQt5.Qt import *
        import sysclass Window(QWidget):def __init__(self):super().__init__()self.setWindowTitle('界面文件加载')self.resize(500, 300)self.addWidget()def addWidget(self):from login import Ui_Form       # 导入模块ui = Ui_Form()                  # 通过模块内的类创建对象ui.setupUi(self)                # 调用对象的setupUi方法,并将self传递进去if __name__ == '__main__':app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())
        
      • B、利用python的多继承特性,来继承界面文件里面的自定义类
      • 创建py文件(load_login_2.py)
        from PyQt5.Qt import *
        import sys
        from login import Ui_UserLoginclass Window(QWidget, Ui_UserLogin):def __init__(self):super().__init__()self.resize(500, 300)self.setupUi(self)      # 调用父类的setuoUi方法self.addWidget()self.setWindowTitle('用户登录')icon = QIcon('icon/1.ico')self.setWindowIcon(icon)def addWidget(self):self.btn_login.clicked.connect(self.btn_click)def btn_click(self):account = self.le_username.text()password = self.le_password.text()print(account, password)if __name__ == '__main__':app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())
        
      • 运行结果

原理讲解

  • 这里我们做一个很简单的界面(一个窗体上面放了一个标签),来解读一下文件代码
    • 在这里插入图片描述
  • 将ui_FormHello.ui文件转成ui_FormHello.py文件,代码如下:
    from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(400, 200)self.label = QtWidgets.QLabel(Form)self.label.setGeometry(QtCore.QRect(100, 70, 72, 15))self.label.setObjectName("label")self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "MainWindow窗体"))self.label.setText(_translate("Form", "标签"))if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QWidget()ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())
    
  • UI文件原理解析
    • 分析这个文件的代码,可以发现这个文件实际上定义了一个类Ui_Form,仔细分析一下这段代码,可以发现其原理和功能
    • (1)Ui_Form类的父类是object,而不是QWidget。
    • (2)Ui_Form类定义了一个函数setupUi(),其接口定义为
      def setupUi(self, Form):
      
    • 其传入的参数有两个,其中self是函数自己,Python中的self类似于C++语言中的this;Form是一个传入的参数,而不是在Ui_Form类里定义的一个变量
    • setupUi()函数的前两行语句是:
      Form.setObjectName("Form")
      Form.resize(400, 200)
      
    • 所以,Form是窗体,是一个QWidget对象,其名称就是在UI Designer里设计的窗体的objectName。但是这个Form不是在类Ui_Form里创建的,而是作为一个参数传入的。
    • (3)创建了一个QLabel类型的对象labe,创建的语句是
      self.label = QtWidgets.QLabel(Form)
      
    • label定义为Ui_Form类的一个公共属性(类似于C++的公共变量),它的父容器是Form,所以label在窗体Form上显示。后面的语句又设置了label的显示位置、大小
    • 注意:在Python语言中,类的接口包括属性(attribute)和方法(method),属性又分为类属性和类的实例属性
    • (4)setupUi()函数的倒数第二行调用了Ui_Form类里定义的另外一个函数retranslateUi(),这个函数设置了窗体的标题、标签labe的文字。实际上,retranslateUi()函数集中设置了窗体上所有的字符串,利于实现软件的多语言界面
    • (5)setupUi()函数的最后一行语句用于窗体上各组件的信号与槽函数的自动连接
    • 特点说明
    • 经过pyuic5编译后,ui_FormHello.ui文件转换为一个对应的Python的类定义文件ui_FormHello.py,类的名称是Ui_Form。有如下的特点和功能。
      • (1)Ui_FormHello.py文件里的类名称Ui_Form与Ui_FormHello.ui文件里窗体的objectName有关,是在窗体的objectName名称前面加“Ui_”自动生成的。
      • (2)Ui_Form类的函数setupUi()用于窗体的初始化,它创建了窗体上的所有组件并设置其属性。
      • (3)Ui_Form类并不创建窗体Form,窗体Form是由外部传入的,作为所有界面组件的父容器
  • 多继承方法原理解析
    • 将窗体UI文件Ui_FormHello.ui编译转换为Python的类定义文件ui_FormHello.py后,就可以使用其中的类Ui_FormHello创建GUI应用程序。
    • Python的面向对象编程支持使用多继承,编写一个程序appMain2.py,代码如下:
      # appMain2.py 多继承方法
      import sys
      from PyQt5.QtWidgets import QWidget, QApplication
      from ui_FormHello import Ui_Formclass QmyWidget(QWidget,Ui_Form):def __init__(self, parent=None):super().__init__(parent)        # 调用父类构造函数,创建QWidget窗体self.Lab="多重继承的QmyWidget"  # 新定义的一个变量self.setupUi(self)              # self是QWidget窗体,可作为参数传给setupUi()self.LabHello.setText(self.Lab)if __name__ == "__main__":app = QApplication(sys.argv)        #创建appmyWidget=QmyWidget()myWidget.show()myWidget.btnClose.setText("不关闭了")sys.exit(app.exec_())
      
    • (1)采用多继承的方式定义了一个类QmyWidget,称这个类为窗体的业务逻辑类,它的父类是QWidget和Ui_Form。(2)在这个类的构造函数中,首先用函数super()获取父类,并执行父类的构造函数,代码是:
      super().__init__(parent)
      
    • 在多继承时,使用super()得到的是第一个基类,在这里就是QWidget。所以,执行这条语句后,self就是一个QWidget对象。
    • (3)调用setupUi()函数创建UI窗体,即
      self.setupUi(self)
      
    • 因为QmyWidget的基类包括Ui_Form类,所以可以调用Ui_Form类的setupUi()函数。同时,经过前面调用父类的构造函数,self是一个QWidget对象,可以作为参数传递给setupUi()函数,正好作为各组件的窗体容器
    • 通过这样的多继承,Ui_Form类中定义的窗体上的所有界面组件对象就变成了新定义的类QmyWidget的公共属性,可以直接访问这些界面组件。例如:
      self.Lab="多重继承的QmyWidget"      # 新定义的一个属性
      self.LabHello.setText(self.Lab)
      
    • 在应用程序创建QmyWidget类的实例对象myWidget后,通过下面的语句设置了界面上按钮的显示文字
      myWidget.btnClose.setText("不关闭了")
      
    • 这种多继承方式有其优点,也有其缺点,表现为以下两方面
      • (1)界面上的组件都成为窗体业务逻辑类QmyWidget的公共属性,外界可以直接访问。优点是访问方便,缺点是过于开放,不符合面向对象严格封装的设计思想。
      • (2)界面上的组件与QmyWidget类里新定义的属性混合在一起了,不便于区分。例如,在构造函数中有这样一条语句
        self.LabHello.setText(self.Lab)
        
      • 其中,self.LabHello是窗体上的标签对象,而self.Lab是QmyWidget类里新定义的一个属性。如果没有明确的加以区分的命名规则,当窗体上的界面组件较多,且窗体业务逻辑类里定义的属性也很多时,就难以区分哪个属性是界面上的组件,哪个属性是在业务逻辑类里新定义的,这样是不利于界面与业务逻辑分离的。
  • 单继承与界面独立封装方法原理解析
    • 针对多继承存在的一些问题,改用单继承的方法,编写另一个程序appMain.py,其代码如下:
      # appMain.py 单继承方法,能更好地进行界面与逻辑的分离
      import sys
      from PyQt5.QtWidgets import QWidget, QApplication
      from ui_FormHello import Ui_Formclass QmyWidget(QWidget):def __init__(self, parent=None):super().__init__(parent)        # 调用父类构造函数,创建QWidget窗体self.__ui=Ui_Form()        # 创建UI对象self.__ui.setupUi(self)         # 构造UIself.Lab="单继承的QmyWidget"self.__ui.LabHello.setText(self.Lab)def setBtnText(self, aText):self.__ui.btnClose.setText(aText)if __name__ == "__main__":app = QApplication(sys.argv)        # 创建app,用QApplication类myWidget=QmyWidget()myWidget.show()myWidget.setBtnText("间接设置")sys.exit(app.exec_())
      
    • (1)新定义的窗体业务逻辑类QmyWidget只有一个基类QWidget
    • (2)在QmyWidget的构造函数中,首先调用父类(也就是QWidget)的构造函数,这样self就是一个QWidget对象。
    • (3)显式地创建了一个Ui_Form类的私有属性self.__ui,即
      self.__ui=Ui_Form()     # 创建UI对象
      
    • 私有属性self.__ui包含了可视化设计的UI窗体上的所有组件,所以,只有通过self.__ui才可以访问窗体上的组件,包括调用其创建界面组件的setupUi()函数。
    • 提示:Python语言的类定义通过命名规则来限定元素对外的可见性,属性或方法名称前有两个下划线表示是私有的,一个下划线表示模块内可见,没有下划线的就是公共的
    • (4)由于self.__ui是QmyWidget类的私有属性,因此在应用程序中创建的QmyWidget对象myWidget不能直接访问myWidget.__ui,也就无法直接访问窗体上的界面组件
    • 为了访问窗体上的组件,可以在QmyWidget类里定义接口函数,例如函数setBtnText()用于设置窗体上按钮的文字。在应用程序里创建QmyWidget对象的实例myWidget,通过调用setBtnText()函数间接修改界面上按钮的文字,即
      myWidget.setBtnText("间接设置")
      
    • 这种单继承的方式,有如下特点:
      • (1)可视化设计的窗体对象被定义为QmyWidget类的一个私有属性self.__ui,在QmyWidget类的内部对窗体上的组件的访问都通过这个属性实现,而外部无法直接访问窗体上的对象,这更符合面向对象封装隔离的设计思想。
      • (2)窗体上的组件不会与QmyWidget里定义的属性混淆。例如,下面的语句:
        self.__ui.LabHello.setText(self.Lab)
        
      • self.__ui.LabHello表示窗体上的标签对象LabHello,它是self.__ui的一个属性;
      • self.Lab是QmyWidget类里定义的一个属性。
      • 这样,窗体上的对象和QmyWidget类里新定义的属性不会混淆,有利于界面与业务逻辑的分离。
      • (3)当然,也可以定义界面对象为公共属性,即创建界面对象时用下面的语句:
        self.ui=Ui_FormHello()
        
      • 这里的ui就是个公共属性,在类的外部也可以通过属性ui直接访问界面上的组件
  • 总结
    • 对比多继承方法和单继承方法,可以发现单继承方法更有利于界面与业务逻辑分离

这篇关于093.PyQt5_QTDesigner_具体使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/204961

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud