基于PyQt5自定义UI的详细教程

2023-12-30 05:42:23


1. 实例:双视图立体匹配与重建的可视化UI

  • 输入:一对左右眼视图的图像。
  • 任务:对输入的一对带相机参数的左右眼图像数据,实现SAD、NCC 两种局部的立体匹配方法进行重建。
  • 输出
    • 基本的交互界面供用户选择立体匹配算法以及输入的图片。
    • 将每种立体匹配方法所用的时间以及图片大小信息显示出来。
    • 可视化重建的结果,如点云,深度图,视差图等,可以使用Meshlab 软件
      或者Open3D 进行可视化

2. 一个简单的UI展示

针对上述实例要求,设计了一个简单的符合要求的UI如下图所示。界面包含图片选择(Picture)、匹配算法选择(Matching algorithm)、成本函数选择(Matching cost)、运行按钮(Run)、图片显示窗口(Picture visualization)、结果显示窗口(Results display)和输出信息窗口(Output information)

在这里插入图片描述


3. 基于PyQt5自定义UI功能

3.1 查询UI中组件的变量名

首先,Qt designer设计的UI中的每一个组件对象都有一个变量名,即下图红框中的“对象”,例如Picture窗口中的图片选项栏对应的变量名就是comboBox,右边的QComboBox是我们在Qt designer界面和所有组件功能的详细介绍中介绍过的一个小组件的父类。默认的组件变量名如下图中所示,当然也可以自定义变量名方便后续编程。

在这里插入图片描述

3.2 使用PyQt5对小组件自定义功能

  • 导入所需的所有包:
# 这里仅展示PyQt5相关包
from PyQt5.QtWidgets import *
from PyQt5 import uic, QtGui, QtWidgets, QtCore
  • 定义UI的类:
class MyWindow(QWidget):
    def __init__(self):
    	self.init_ui(self)  # 初始化设计的界面
    	
    def init_ui(self, self1):
    	"""
    	获取UI中需要自定义的组件的变量名
    	"""
  • init_ui()函数,注意变量名与Qt designer中对象一一对应:
def init_ui(self):
	self.ui = uic.loadUi("./Stereo_matching.ui", self1)  # 加载 .ui 文件
	
	self.scenario_name = self.ui.comboBox.currentText()  # 双视图
	self.matching_algorithm = self.ui.comboBox_5.currentText()  # 匹配算法
	self.matching_cost = self.ui.comboBox_6.currentText()  # 匹配cost
	
	self.graphicsView = self.ui.graphicsView  # 左右视图
	self.graphicsView_2 = self.ui.graphicsView_2  # 结果
	
	self.text = self.ui.textBrowser  # 显示结果
	
	# 绘制当前选择的双视图
	self.ui.comboBox.currentIndexChanged.connect(self.draw_current_scenario)
	
	# 给RUN按钮绑定事件
	run_button = self.ui.pushButton
	run_button.clicked.connect(self.run)
  • 根据运行逻辑,当我们选择一对双视图之后首先应该实时绘制出来,方便用户根据实际图片决定是否需要更换双视图的选择。所以我们需要定义一个信号与槽(Signals and Slots)函数,在小组件comboBoxgraphicsView 之间建立交互,即上一段代码中的self.ui.comboBox.currentIndexChanged.connect(self.draw_current_scenario),这行代码的含义是一旦comboBox中当前的索引改变(即当前选项改变),则执行self.draw_current_scenario()函数。这里,我们将self.draw_current_scenario()函数定义如下(注意形参为self的函数是UI类内函数,其他均为类外全局函数):
def draw_current_scenario(self):
    self.text.append("Drawing pictures...")
    # 获取当前的双视图
    self.scenario_name = self.ui.comboBox.currentText()

    # 读取左右视图
    left_image, right_image, groundtruth_image, mask_image = import_image(self.scenario_name)
    # 绘制左右视图、groundtruth、mask
    plot_image(self.scenario_name, left_image, right_image, groundtruth_image, mask_image)

    self.text.append("The picture's size: " + str(left_image.shape))
    self.text.append("Click RUN to start.\n")

    self.picture_visualization()
    
def picture_visualization(self):
    pixmap = QtGui.QPixmap(f"./results/{self.scenario_name}_input.png")

    # 创建 QGraphicsScene
    scene = QtWidgets.QGraphicsScene(self)
    scene.addPixmap(pixmap)
    # 创建 QRectF 对象
    rect = QtCore.QRectF(pixmap.rect())
    scene.setSceneRect(rect)

    # 设置 QGraphicsView
    self.graphicsView.setScene(scene)

    # 调整视图以适应场景的内容
    self.graphicsView.fitInView(scene.sceneRect(), QtCore.Qt.KeepAspectRatio)

def import_image(scenario_name):
    """
    读取左右视图
    """
def plot_image(scenario_name, left_image, right_image, groundtruth_image, mask_image):
    """
    绘制左右视图、groundtruth、mask等
    """
  • 在选择一对双视图之后,用户需要选择匹配算法和cost算法,最后点击RUN按钮运行。由于选择匹配算法和cost算法时界面不需要有其他功能体现,所以不需要做额外定义,主要RUN之前更新一下当前的双视图、匹配算法、匹配cost即可。点击RUN按钮运行同样需要定义一个信号与槽函数run_button.clicked.connect(self.run)
def run(self):
    # 获取当前的双视图、匹配算法、匹配cost
    self.scenario_name = self.ui.comboBox.currentText()
    self.matching_algorithm = self.ui.comboBox_5.currentText()
    self.matching_cost = self.ui.comboBox_6.currentText()

    # 调用main.py中的run_stereo_matching函数
    t1 = time.time()
    result_pic, acc = run_stereo_matching(self.scenario_name, self.matching_algorithm, self.matching_cost,)

    if result_pic is not None:
        # 显示结果
        self.result_display()

        t2 = time.time()
        self.text.append(f"Runtime: {t2 - t1:.3f}s")
        self.text.append(f"The result's size: {str(result_pic.shape)}")
        if acc is not None:
            self.text.append(f"Acc: {acc:.5f}\n")
    else:
        self.text.append("Warning! NCC is not applicable to this picture!\n")

def run_stereo_matching(scenario_name, matching_algorithm_name, matching_cost_name):
    """
    运行双视图立体匹配
    """
  • 最后,运行结果需要呈现在Display窗口,同时运行日志要在Output information窗口中输出。其中运行日志可以通过self.text.append()进行实时输出,运行结果绘制类似picture_visualization(self)函数,定义如下:
def result_display(self):
    pixmap = QtGui.QPixmap(f"./results/{self.scenario_name}_{self.matching_algorithm}_{self.matching_cost}.png")

    # 创建 QGraphicsScene
    scene = QtWidgets.QGraphicsScene(self)
    scene.addPixmap(pixmap)
    # 创建 QRectF 对象
    rect = QtCore.QRectF(pixmap.rect())
    scene.setSceneRect(rect)

    # 设置 QGraphicsView
    self.graphicsView_2.setScene(scene)

    # 调整视图以适应场景的内容
    self.graphicsView_2.fitInView(scene.sceneRect(), QtCore.Qt.KeepAspectRatio)
  • 最最后,运行UI:
if __name__ == "__main__":
    app = QApplication(sys.argv)

    w = MyWindow()
    # display the window
    w.ui.show()

    sys.exit(app.exec_())

创作不易,麻烦点点赞和关注咯!

文章来源:https://blog.csdn.net/qq_43811536/article/details/135284469
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。