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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念