OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门

news2024/11/17 21:36:51

欢迎关注『OpenCV-PyQT项目实战 @ Youcans』系列,持续更新中
OpenCV-PyQT项目实战(1)安装与环境配置
OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门
OpenCV-PyQT项目实战(3)信号与槽机制

文章目录

    • 1. QtDesigner 和 PyUIC 的快速入门
      • 1.1 QtDesigner 的启动和入门
      • 1.2 PyUIC 的使用
      • 1.3 编写 Python 应用程序调用图形界面
    • 2. 创建主窗口
      • 2.1 窗口类型
      • 2.2 编辑窗口的属性
      • 2.3 图形界面设计的预览
    • 3. 建立菜单栏
      • 3.1 建立一级菜单
      • 3.2 建立二级菜单
      • 3.3 关联动作
    • 4. 建立工具栏
      • 4.1 添加工具栏
      • 4.2 添加和编辑动作对象
      • 4.3 向工具栏添加动作对象
    • 5. 从面向过程到面向对象
      • 5.1 面向过程的程序设计
      • 5.2 面向对象的程序设计


1. QtDesigner 和 PyUIC 的快速入门

在上节中,我们直接编程设置窗口参数和定义对象,实现简单的 PyQt5 图形界面。对于复杂的图像界面,通常使用 QtDesigener 来设计图形界面,比直接编程方便的多。

使用 QtDesigner 开发 PyQt5 图形界面的基本步骤是:
(1)使用图形界面设计工具 QtDesigner 进行图形界面设计,生成 .ui 文件;
(2)使用 UI 转换工具 PyUIC 将 .ui 文件转换为 .py 文件;
(3)编写一个 Python 应用程序调用 .py 界面文件,就可以实现 Python 平台的 GUI 编程。

虽然这些步骤看起来有些罗嗦,其实是非常简单方便的。下面我们用一个简单的例程详细讲解每一个步骤的操作。


1.1 QtDesigner 的启动和入门

(1)- 运行 PyCharm,打开建立的 Python Project,例如 Project 为 PyqtDemo。
(2)- 从顶部菜单栏选择:Tools -> ExternalTools -> QtDesigner,弹出如下的 QtDesigner 运行窗口。

在这里插入图片描述


(3)- 新建窗体
首次运行 QtDesigner 时可能会自动弹出 “新建窗体” 对话框,也可以通过菜单栏选择:“文件 -> 新建” 或快捷键 “Ctrl+N” 唤起 “新建窗体” 对话框。
在 “新建窗体” 窗口的左侧菜单选择 “MainWindow” 新建一个图形窗口。

(4)- 设计图形界面

QtDesigner 的使用界面与 AutoCAD 等设计软件类似,很好上手。

主界面分左中右三部分,左侧是各种备选的控件对象,右侧上方的 “对象查看器” 显示控件的树状结构,右侧下方的 “属性编辑器” 显示控件的各种属性,中间部分用于显示所设计的界面。

新建的窗口 “MainWindow” 虽然是一个空白的图形窗口,但已经生成了 centralwidget、menubar、statusbar 三个基本控件,可以在右侧上方 “对象查看器” 查看这些控件及结构。

下面我们为新建的图形窗口添加几个图形控件:

在这里插入图片描述


新建一个按钮控件:

  • 从左侧控件栏的 Button 中选择 PushButton 按钮,鼠标左键点中 PushButton 按钮不放,移动鼠标将 PushButton 按钮拖动到中间的新建图形窗口内的任意位置,松开鼠标左键,就在图形窗口位置生成了一个 PushButton 按钮对象。
  • 鼠标左键点击图形窗口中的这个 PushButton 按钮对象,拖动按钮可以调整控件的位置,对于其它控件也可以通过鼠标拖动来调整位置。
  • 鼠标选中 PushButton 按钮对象,控件周围的边界位置上就出现 8个蓝色的点,表示控件被选中,这时可以在右侧的 “属性编辑器” 内对对象的属性进行编辑和修改,例如:
    • 将 PushButton 对象的高度修改为 120,宽度修改为 40;
    • 将 PushButton 对象的 “QAbstractButton->text” 修改为 “测试按钮”;

新建一个文本显示框控件:

  • 从左侧控件栏的 InputWidget 中选择 TextEdit 按钮,鼠标左键选中 TextEdit 按钮拖动到新建图形窗口内的,松开鼠标左键就在图形窗口生成了一个 TextEdit 对象。
  • 鼠标选中 TextEdit 对象,在右侧的 “属性编辑器” 内可以对对象的属性进行编辑和修改,例如:
    • 将 TextEdit 对象的高度修改为 300,宽度修改为 200;
    • 对于 TextEdit 对象的显示内容可以用 html、markdown 等格式编辑,也可以鼠标双击 TextEdit 对象唤出 html 编辑对话框,输入希望显示的内容。

现在,我们就已经用 QtDesigner 完成了一个基本的图形界面。

(5)- 将设计的图形界面保存为 .ui文件
保存文件就不赘述了,菜单、工具按钮和快捷键都可以,例如保存为 uiDemo1.ui。

注意文件的保存路径,默认保存在添加 QtDesigner 工具时 “Working directory” 所设置的路径,当然也可以另存到其它路径。
本文 3.2 添加 QtDesigner 工具 中 “Working directory” 填写 “$ProjectFileDir$\program”,默认将 .ui 文件保存在当前 Project 路径下的 \program 子目录中。
本文的项目默认设置将 .py 文件也保存在当前 Project 路径下的 \program 子目录中,在应用程序编程时就可以直接导入图形界面文件。
如果 PyChrm 或 QtDesigner 设置的文件保存路径不同,要注意导入图形界面文件时设置和使用正确的路径。


1.2 PyUIC 的使用

(1)- 运行 PyCharm,打开 Python Project,刚才用 QtDesigner 建立的 uiDemo1.ui 文件显示在左侧 Project -> PyqtDemo -> program 显示框中。
如果该 .ui 文件没有显示,说明环境变量路径设置不同,可以重新设置,也可以在保存 .ui 文件时另存到当前 Project 路径下的 \program 子目录中。
(2)- 鼠标选中 .ui 文件,点击鼠标右键唤出下拉菜单,选择:ExternalTools -> PyUIC,点击鼠标左键运行,PyUIC 将选中的 .ui 文件转换为 .py 文件,在该路径生成 uiDemo1.py 文件。

在这里插入图片描述


uiDemo1.py 文件的内容如下。注意该文件不需要编程实现,而是通过 PyUIC 自动生成的。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'uiDemo1.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(600, 480)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(150, 300, 120, 40))
        self.pushButton.setObjectName("pushButton")
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(50, 50, 300, 200))
        self.textEdit.setObjectName("textEdit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 600, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "测试按钮"))
        self.textEdit.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">第一个 PyQt 图形界面。</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">点击“测试按钮”清空显示文本。</p></body></html>"))


1.3 编写 Python 应用程序调用图形界面

我们编写一个主程序调用设计的图形界面 uiDemo1.py,就可以完成一个图形界面应用程序。

# GUIdemo2.py
# Demo2 of GUI by PqYt5
# Copyright 2021 Youcans, XUPT
# Crated:2021-10-06

from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import uiDemo1

if __name__ == '__main__':
    app = QApplication(sys.argv)  # 创建应用程序对象
    MainWindow = QMainWindow()  # 创建主窗口
    ui = uiDemo1.Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()  # 显示主窗口
    sys.exit(app.exec_())  # 在主线程中退出

在主程序 GUIdemo2.py 中,我们通过 “import uiDemo1” 导入了 图形界面 uiDemo1.py。

运行程序 GUIdemo2,将弹出如下的图形界面:

在这里插入图片描述


如果你能得到这个图形界面,就说明 Pyqt5 和 QtTools 已经安装成功、配置正确了。

不过,GUIdemo2 中的按钮和点击之后并没有任何反应,这是因为我们还没有设置这些控件所触发的动作和应用。

在以后的程序中,我们将不断增加和丰富这个图形界面应用程序。



2. 创建主窗口

上文中我们建立的图形界面程序 GUIdemo2.py,通过导入图形界面 uiDemo1.py,已经实现了主窗口的创建。

2.1 窗口类型

进一步地,在 QtDesigner 创建主窗口有三种类型:QMainWindow、QDialog 和 QWidget。

  • QMainWindow:包括菜单栏、工具栏、状态栏和标题栏,常用于应用程序的窗口。
  • QDialog:没有菜单栏、工具栏、标题栏,常用于对话框的窗口。QtDesigner 中进一步提供了:没有默认按钮的对话框、底部按钮的对话框和右侧按钮的对话框可供选择。
  • QWidget:不确定窗口的类型。

新建应用程序窗口,通常可以选择 MainWindow 创建主窗口的图形界面。QtDesigner 创建的 “MainWindow” 虽然是一个空白的图形窗口,但已经生成了 centralwidget、menubar、statusbar 三个基本控件,可以在右侧上方 “对象查看器” 查看这些控件及结构。


2.2 编辑窗口的属性

在 QtDesigner 中用鼠标选中主窗口,或者在右侧的 “对象查看器” 中选中对象 “MainWindow”,此时右侧中部的 “属性编辑器” 将显示对象 “MainWindow” 的属性。在 “属性编辑器” 内可以对对象的属性进行编辑和修改。

  • 对象名称(objectName)

当前窗口对象的名称(objectName)默认为 “MainWindow”。对象名称可以修改,但小白不要轻易去修改。在生成的 .ui 文件和 .py 文件中将定义一个类 Ui_MainWindow,在主程序调用图形界面时也会实例化类。

如果修改了对象名称,则主程序中需要进行相应修改。一些例程中定义类 Ui_Form,就是将窗口对象名称设为 “Form”。

  • 窗口标题(windowTitle)

当前窗口对象的标题(windowTitle)默认值也是 “MainWindow”,因此容易将其与对象名称(objectName)混淆。

窗口标题显示在应用程序窗口的左上角,通常是程序名。窗口对象的标题是可以根据需要修改的,本例修改为 “数字图像处理”。

  • 应用图标(windowIcon)

当前窗口对象的图标(windowIcon)默认值 Null,没有图标。
- 点击 “属性编辑器” 下 windowIcon 行的右侧空白处,将出现 " [Theme]“、”…" 和 “ ▽ \triangledown ” 按钮的选项框
- 点击 “ ▽ \triangledown ” 按钮,从 “选择资源”、“选择文件”、“选择主题” 三个选项选中 “选择文件”,从文件夹中选择一个图标文件。
本例在 Python 当前 Project 路径下建立了 \image 目录,图标和图片文件都保存在 \image 目录。本例选择 youcans.png 作为应用程序图标,读者可以任选自己的图标文件。

在 “属性编辑器” 内也可以对其它对象属性进行编辑和修改,例如:

  • 将 MainWindow 对象的高度修改为 800,宽度修改为 600;

2.3 图形界面设计的预览

在 QtDesigner 菜单中选择:窗体 -> 预览,就可以预览设计的图形界面,还可以选择预览不同操作系统的显示效果。这使我们不需要编写主程序就可以预览图形界面的显示效果,以便进行修改。

刚才所创建的应用程序窗口预览如下图所示:

在这里插入图片描述



3. 建立菜单栏

3.1 建立一级菜单

QtDesigner 创建的 “MainWindow” 图形窗口,自动生成了顶部菜单栏 menubar,在图形窗口左上角显示有文本输入框 “在这里输入”。

输入菜单对象(menu)的标题(title):

  • 鼠标点击文本输入框 “在这里输入”,选中文本输入框,控件的边框变为紫色;
  • 再双击选中的控件,出现激活的文本输入框,就可以输入所要建立菜单的标题;
  • 输入菜单标题后回车结束,就建立了一个一级菜单,例如:将菜单标题设为 “文件”。

输入菜单对象的标题,以及修改菜单对象的属性,更通用的方法是:

  • 在 QtDesigner 右侧的 “对象查看器” 中选中对象 “menu”,此时右侧中部的 “属性编辑器” 将显示对象 “menu” 的属性。
  • 在 “属性编辑器” 内选择 “title” 属性,将其修改为菜单标题:“文件”。

建立一级菜单 “文件” 后,菜单栏中在 “文件” 右侧又出现新的文本输入框 “在这里输入” ,按照以上操作可以接着建立更多的菜单对象。
本例中还建立了一个一级菜单对象 “menuQuit”,标题为 “退出”。


3.2 建立二级菜单

QtDesigner 创建二级菜单,实际上是将动作(action)添加到一级菜单。

  • 鼠标点击一级菜单对象 “文件”,出现两个下拉菜单选项:“在这里输入” 和 “添加分割符”。

  • 选中 “在这里输入”,输入二级菜单的标题。
    我们发现这时文本输入框不接受中文输入,于是输入英文 “Open”,生成二级菜单项。观察 QtDesigner 右侧的 “对象查看器”,在 menubar-menu 下新建的并不是控件对象,而是动作 actionOpen。这就是刚才文本输入框不接受中文的原因。

  • 编辑动作 actionOpen 的属性,可以将属性 “text” 由 “Open” 修改为中文 “打开”。这时再点击菜单 “文件”,下拉菜单中的动作 actionOpen 就显示为中文 “打开”。
    类似地,在一级菜单对象 “文件” 下,再建立两个二级菜单(动作)“Save”、“Close”,并将其属性 “text” 修改为 “保存”、“关闭”。

  • 点击二级菜单/动作 “打开”,在其右侧有个 “+” 按钮,点击后可以创建新的下一级菜单。
    注意:这时刚才建立的动作对象 “menu-actionOpen” 被自动删除了,同时生成了一个菜单对象 “menu-menu_2”。这是因为只有最下级的菜单项被设为动作对象 “QAction”,而上级菜单项只能是菜单对象 “QMenu”。

本例还在一级菜单对象 “menuQuit” 下建立了动作对象 “actionQuit”,标题为 “Quit”。

预览一下应用程序窗口,就可以看到刚才建立的菜单栏:

在这里插入图片描述


3.3 关联动作

我们已经在图形界面建立了菜单项,并为菜单项添加了动作对象。但是动作对象中的 “打开”、“保存”、“关闭” 只是这些动作对象的名称和描述,并没有定义或关联具体的动作。

因此在点击菜单时,虽然会显示对应的菜单选项,但并不会真正进行 “打开”、“关闭” 的动作。下面以一级菜单 “退出” 下的动作对象 “actionQuit” 为例,讲解将关闭动作(close)关联到动作对象 “actionQuit” 。

这里要简单解释一下 PyQt5 中的信号与槽机制。信号与槽是 PyQt5 中对象之间进行通信的机制。简单地说,对某个信号与某个槽函数进行连接之后,当该信号被触发时,自动执行对应的槽函数。

因此,将一个动作关联到一个动作对象(或其它对象),就是定义了对象的动作(例如点击菜单项)作为信号,并连接到对应的动作处理函数。当该信号被触发时,将自动执行对应的槽函数(动作处理函数)。例如,将点击动作对象 “actionQuit” 作为信号,连接到动作处理类 close(),则在该对象被点击时就会自动执行类 close(),进而执行 QDialog 类中的closeEvent() 方法。

将动作函数 close() 关联到动作对象 “actionQuit” 的操作如下:

  • 从在 QtDesigner 右侧下方窗口 “信号/槽编辑器”,点击绿色的 “+” 新建一个信号/槽连接;
  • 点击 “<发送者>”,从菜单中选择对象 “actionQuit”;
  • 点击 “<信号>”,从菜单中选择 “triggered()”;
  • 点击 “<接收者>”,从菜单中选择 “MainWindow”;
  • 点击 “<槽>”,从菜单中选择 “closed()”。

以上操作的作用是:发送者 对象 “actionQuit” 触发 “triggered()” 时,接收者 对象"MainWindow" 执行槽函数 “closed()”。

QtDesigner 中 “信号/槽编辑器” 的使用确实比较繁琐,特别是对于菜单栏和工具栏的支持并不友好,而且不支持一级菜单对象直接连接槽函数。

相比而言,对于菜单栏和工具栏,在主程序中通过 connect() 建立信号/槽连接则更加简便:

self.actionQuit.triggered.connect(MainWindow.close)


4. 建立工具栏

工具栏/工具条是图形界面中的常用组件,将一组按钮控件排成一行放在图形窗口的顶部。

4.1 添加工具栏

QtDesigner 中 添加工具栏的操作很简单,但是不太好找:

  • 单击鼠标右键,选择 “添加工具栏”。
  • 也可以选择 “Add Toolbar to Other Area”,将工具栏添加到窗口的左侧、右侧或底部。

添加工具栏以后,在顶部菜单栏的下方出现工具栏。新添加的工具栏是空的,非常窄,不加注意就容易被忽略。


4.2 添加和编辑动作对象

工具栏中只能添加动作控件(QAction),因此要先添加/编辑动作。

其实上文中菜单栏中也只能添加动作控件,但是菜单栏允许在输入二级菜单时直接添加动作控件(QAction),而工具栏只允许选择已有的动作控件添加。

在 QtDesigner 右侧下方窗口选择 “动作编辑器”,可以新建或编辑动作对象。

在 1.2 建立二级菜单时,我们已经建立了 actionOpen、actionSave、actionClosr、actionQuit等动作对象。这些动作对象显示在 “动作编辑器” 子窗口中。

添加/编辑动作对象步骤为:

  • 点击 “动作编辑器” 子窗口工具栏的第一个图标按钮 “新建”,则弹出 “新建动作” 对话框;
  • 双击 “动作编辑器” 中的动作对象,则弹出 “编辑动作” 对话框,可以编辑已有动作对象的属性;

“新建动作” 与 “编辑动作” 对话框的结构是相同的,对照已有动作对象的属性更容易理解 “新建动作” 对话框中属性选项的含义:

  • “文本” 指动作的标题,是控件的显示内容,可以是中文或英文,例如 “打开(Open)”;
  • “对象名称” 指动作的名称,是程序中调用对象的名称,只能是英文,例如 “actionOpen”;
  • “图标” 指工具栏中所显示的动作图标,点击 “ ▽ \triangledown ” 按钮,选择 “选择文件” 选项,可以从文件夹中选择图标文件。

本例添加了动作对象:“actionSetup/设置”、“actionHelp/帮助”,并编辑动作对象 “actionQuit/退出” 设置动作图标。


4.3 向工具栏添加动作对象

从 QtDesigner 右侧下方窗口选择 “动作编辑器”,鼠标左键点击选中其中的动作控件,长按鼠标不放,拖动到图形窗口的工具栏后松开,就将动作控件添加到工具栏中。

如果动作对象设有图标,则在工具栏显示动作图标;如果动作对象没有设置图标,则在工具栏显示动作标题的文本信息。

本例将 “动作编辑器” 中的 6个动作对象都添加到工具栏。

预览一下应用程序窗口,就可以看到刚才建立的工具栏。

该窗口的工具栏中 “打开”、“保存”、“关闭” 三个动作对象显示为文字,而 “设置”、“帮助”、“退出” 三个动作对象显示为图标,显得不伦不类,这主要是为了示范不同的显示选项。随后我们会进行修改,为 “打开”、“保存”、“关闭” 等动作对象添加图标。

在这里插入图片描述



5. 从面向过程到面向对象

5.1 面向过程的程序设计

我们编写一个主程序调用设计的图形界面 uiDemo3.py,就可以完成一个图形界面应用程序。

在 QtDesigner 将设计的图形界面保存为 uiDemo3.ui。在 PyCharm 选中 uiDemo3.ui 文件,点击鼠标右键唤出下拉菜单,选择:ExternalTools -> PyUIC,点击鼠标左键运行 PyUIC 将选中的 .ui 文件转换为 .py 文件,在该路径生成 uiDemo3.py 文件。

# GUIdemo3.py
# Demo3 of GUI by PyQt5
# Copyright 2023 youcans, XUPT
# Crated:2023-01-28

from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import uiDemo2  # 导入图像界面设计文件

if __name__ == '__main__':
    app = QApplication(sys.argv)  # 创建应用程序对象
    MainWindow = QMainWindow()  # 创建主窗口
    ui = uiDemo2.Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()  # 显示主窗口
    sys.exit(app.exec_())  # 在主线程中退出

在主程序 GUIdemo3.py 中,我们通过 “import uiDemo2” 导入了 图形界面 uiDemo2.py。

运行程序 GUIdemo3,弹出的图形界面与 3.3 中的预览效果是一致的,只是添加图标后的动作对象 “打开”、“保存”、“关闭” 在工具栏已经显示为图标。

在这里插入图片描述


在例程 GUIdemo3.py 中,我们在主程序中创建主窗口后,直接调用 UI 中的 Ui_MainWindow()。这是面向过程的程序设计方法。

随着项目的不断深入,需要处理更加丰富的图形界面和实现更加复杂的软件功能,程序的规模越来越大,程序的结构越来越复杂,面向过程的程序设计无法满足 GUI 交互产品的需求。


5.2 面向对象的程序设计

面向对象的程序设计使程序的结构更加清晰,从而易于阅读、理解、开发和维护,非常适合开发大规模、多任务的图形界面应用软件。PyQt5 中的类、对象、控件和方法,都是面向对象的程序设计的概念。因此,从本文开始我们采用面向对象的程序设计方法,来编写图形界面的主程序。

例程 GUIdemo3b.py 如下:

# GUIdemo3b.py
# Demo3b of GUI by PyQt5
# Copyright 2023 youcans, XUPT
# Crated:2023-01-28

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from uiDemo2 import Ui_MainWindow  # 导入 uiDemo2.py 中的 Ui_MainWindow 界面类

class MyMainWindow(QMainWindow, Ui_MainWindow):  # 继承 QMainWindow 类和 Ui_MainWindow 界面类
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)  # 初始化父类
        self.setupUi(self)  # 继承 Ui_MainWindow 界面类

if __name__ == '__main__':
    app = QApplication(sys.argv)  # 在 QApplication 方法中使用,创建应用程序对象
    myWin = MyMainWindow()  # 实例化 MyMainWindow 类,创建主窗口
    myWin.show()  # 在桌面显示控件 myWin
    sys.exit(app.exec_())  # 结束进程,退出程序

在这个例程中,我们创建了一个类 MyMainWindow(),它继承了 QtWidgets.QMainWindow 类方法和导入的 uiDemo2.py 中的 Ui_MainWindow 界面类。

“super(MyMainWindow, self).init()”:初始化父类,把 MyMainWindow 的对象 self 转成父类 QMainWindow 对象,并调用 init 函数。

“self.setupUi(self)”:继承 uiDemo2.py 中的 Ui_MainWindow 界面类,调用 Ui_MainWindow 类的setupUi() 方法。

不熟悉面向对象程序设计的小白,如果看不懂这段程序也没有关系,保存下来照猫画虎就可以了。

例程 GUIdemo3b.py 的作用和效果与 例程 GUIdemo3.py 完全相同。

GUIdemo3 中只有 “退出” 按钮和菜单项有效,点击后退出应用程序。其它按钮和菜单项还是无效的。这是因为我们还没有为这些控件关联动作程序(连接槽函数)。我们将在下一节学习信号与槽函数的连接。


【本节完】


版权声明:
原创作品,转载必须标注原文链接:https://blog.csdn.net/youcans/article/details/128766698
Copyright 2023 youcans, XUPT
Crated:2023-01-28

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184232.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】final的关键字和final的四种用法

final定义 final翻译成中文的意思是 “最终” &#xff0c; 它是java当中的一个关键字&#xff0c;使用final修饰的对象不允许修改或替换其原始值或定义。 假如当final修饰一个类的时候&#xff0c;是不能被其他类继承的。 final的四种用法 修饰类修饰方法修饰变量修饰参数 1.…

Oracle 里的优化器

对于关系型数据库而言&#xff0c;优化器是最核心的部分。主要是因为优化器负责解析SQL。而大家都是通过SQL来访问存储在数据库中的数据。故此&#xff0c;优化器的好坏直接决定该关系型数据库的强弱。 同时&#xff0c;想要做好SQL优化&#xff0c;就必须深入了解优化器。这是…

源表的基础知识

浅谈“源表”的定义、功能及应用 源表与传统电源的区别 源表速度更快&#xff1b; 源表电流、电压分辨率更高&#xff1b; 源表是四象限&#xff0c;可以正电压&#xff08;源表提供给外部&#xff09;负电流&#xff08;外部灌入源表&#xff09;或者负电压、正电流。 传统电…

3.组件的基本用法

目录 1 创建组件 1.1 用函数创建组件 1.2 使用类创建组件 2 项目上组件的使用方式 3 事件处理 3.1 事件绑定 3.1.1 类组件绑定事件 3.1.2 函数组件绑定事件 3.2 事件对象 4 组件状态 4.1 初始化状态 4.2 获取状态 4.3 设置状态 4.3.1 箭头函数 4.…

win10下Elasticsearch安装配置完整教程

一、在安装Elasticsearch引擎之前&#xff0c;必须安装ES需要的软件环境&#xff0c;安装Java JDK和配置JAVA_HOME环境变量 二.安装ElasticSearch服务&#xff0c;下载和安装es包 https://www.elastic.co/downloads/past-releases Elasticsearch 8.6.1 | Elastic 安装成功之…

数据结构 第五章 数组和广义表

还是会想你&#xff1a;点击收听 1 基本知识点 1、数组可以看作是下标和值的偶对的集合(具有相同类型的数据元素) 注意&#xff1a;数组是同类型值的集合&#xff1f;**错误**2、数组的存储方式&#xff1a;以行为主序(一行存储完成之后继续存储下一行)、以列为主序(一列存储…

【C++修行之路】C++入门之深剖变量

&#x1f37f;本文主题&#xff1a;C语法中的变量 &#x1f388;更多内容&#xff1a;C较C的改进 &#x1f495;我的主页&#xff1a;蓝色学者 文章目录前言概念什么是变量变量名变量类型为什么要有不同数据类型各自数据类型的本质结语前言 大家好久不见&#xff0c;今天是我…

22.1.29打卡 2023牛客寒假算法基础集训营1 ACDHKLM

2023牛客寒假算法基础集训营1_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 网上高质量题解太多了, 我这就作为打卡日报随便写写 A 四个变量 a b记录两队得分 c d记录两队最多还能获得的得分 简单模拟 /* ⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿…

Ruoyi-Cloud框架学习-【02 Redis安装搭建+Ruoyi下载+Nacos数据库配置】

Redis服务端与客户端的安装与搭建 参考该博文 https://joycez.blog.csdn.net/article/details/128776284?spm1001.2014.3001.5502 安装文件 链接&#xff1a;https://pan.baidu.com/s/1v19C9Dhh-ZkNQ8l1RVGQkA 提取码&#xff1a;6mim Ruoyi-Cloud下载以及数据库配置 1、前…

MySQL主从复制的数据同步延迟(二)

1、介绍 主从复制环境在单机应用的时候没有问题&#xff0c;但是在实际的生产环境中&#xff0c;会存在 复制延迟 的问题 查看从库同步状态 在从库中执行 show slave status\G &#xff1a; mysql> show slave status\G *************************** 1. row **************…

Matlab论文插图绘制模板第73期—带等高线的光影曲面图

在之前的文章中&#xff0c;分享了Matlab曲面图的绘制模板&#xff1a; 光影曲面图&#xff1a; 带等高线的曲面图&#xff1a; 进一步&#xff0c;再来看一下带等高线的光影曲面图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;Matlab论文插图绘制模板系…

make <board_name>_defconfigmake menuconfig

1.make <board_name>_defconfig (1)在uboot的顶层目录的Makefile中查找目标&#xff08;defconfig无法查到&#xff09;&#xff0c;检索config&#xff0c;找到目标config和目标%config 因为我们的目标为<board_name>_defconfig&#xff0c;所以需要看的是有通配…

发现了一个提取时间序列技术指标的神器

互联网上有一个最简单而又强大的技术库&#xff0c;叫做pandas_ta。这个python库为你提供了一个简化的API&#xff0c;让你从时间序列中提取技术分析指标。今天我将和大家一起学习这个库。记得点赞、收藏&#xff5e; 虽然你可能会将这些函数应用于股票价格&#xff0c;但你可…

python开发环境搭建实践

这里写自定义目录标题前言搭建过程anaconda下载与安装下载安装配置环境变量pycharm下载和安装下载安装激活总结前言 新年新气象&#xff0c;我也把电脑进行了重装系统。所以现在需要重新搭建各种开发环境&#xff0c;也不能说是各种&#xff0c;因为我只会python和Java。 先搭…

全国产交换机基本介绍(分类、性能指标、硬件构成及工作方式)

关于全国产交换机基础知识&#xff0c;您了解多少呢&#xff1f;来和海翎光电的小编一起学习一下吧&#xff01; 一、交换机的分类与性能指标 1.1 交换机的分类 按照网络构成方式来分的话&#xff0c;交换机分为三类&#xff1a;接入层交换机、汇聚层交换机和核心层交换机。按照…

93.transformer、多头注意力以及代码实现

1. Transformer架构 2. 多头注意力 3. 数学上来解释多头注意力 4. 有掩码的多头注意力 5. 基于位置的前馈网络 6. 层归一化 batch norm&#xff1a;比如说一行是一个样本&#xff0c;那么BN就是对一列进行归一化&#xff0c;就是对所有数据项的某一列特征进行归一化 layer nor…

【数据结构和算法】了解认识栈,并实现栈的相关函数

到现在我们了解并认识了线性表的概念&#xff0c;动态、静态顺序表的建立&#xff0c;以及两种链表的实现&#xff0c;接下来我们要认识一个新的内容&#xff0c;新的概念&#xff0c;栈&#xff0c;是基于顺序表或者链表的一种新型数据结构。 目录 一、栈是什么&#xff1f; …

RabbitMQ入门中篇

本篇博文目录一.Spring整合RabbitMQ1.导入依赖2.生产者3.消费者4.测试二.SpringBoot整合RabbitMQ1.导入依赖2.生产者3.消费者4.测试三.代码下载一.Spring整合RabbitMQ 在spring项目中使用RabbitMQ的Exchange模式的Topics&#xff0c;项目分为消费者spring项目和生产者spring项目…

Centos7安装kvm服务器

Centos7安装kvm服务器什么是kvm检查硬件是否支持kvm虚拟化启用嵌套虚拟化(可选)查看是否启用嵌套虚拟化嵌套虚拟化立即生效(临时)重新加载模块并验证虚拟机硬件直通虚拟机内查看嵌套虚拟化是否成功安装kvm服务器安装kvm的所有包(不推荐)启动libvirt服务查看是否正确设置了虚拟化…

Linux操作系统之线程安全

一、引入线程安全关于strtok函数不能在多线程中使用&#xff0c;为什么&#xff1f;运行结果原因如下&#xff1a;在strtok内部会有一个全局变量静态指针&#xff08;static char* ptr&#xff09;&#xff0c;一开始指针指向主线程的a&#xff0c;等到后面子线程开始分割时&am…