PySide6从0开始学习的笔记(十四)创建一个简单的实用UI项目

至此,我们已经具备了创建一个简单的基于QT的UI项目的能力,网络和官网上也有很多范例可供参考,至于是使用pycharm还是QT creator作为平台,是使用QT designer还是纯Python代码进行画面布局,根据自己的喜好和能力以及项目性质进行选择即可,没有哪一个是最好。有了一定的实践经验后,最好打造属于自己的应用框架并保存为基本模板,以供日后随时复制使用,提高工作效率。

下面从头记录使用pycharm+designer+pyuic创建一个新项目的过程。


一、环境准备和创建项目

我已经提前创建了名称为yolo的conda环境,并安装了YOLO V11和PySide6,pycharm已经配置好了Qt Designer和pyuic。

YOLO的环境配置见:https://blog.csdn.net/xulibo5828/article/details/145636247

PySide6的安装则只需要一条指令:

python 复制代码
pip install pyside6

pycharm中配置Qt Designer和pyuic的方法见:https://blog.csdn.net/xulibo5828/article/details/156114002


在pycharm中新建项目,选择创建好的名称为yolo的conda环境作为解释器:

  • 在项目根目录下新建文件夹:UI、JOB、tmp,分别存放界面文件、业务文件和临时文件。
  • 在项目根目录下新建文件main.py作为主程序。

新项目创建完成。


二、新建主窗口ui文件

  • 打开designer,新建Main Window:
  • 拖入一个按钮到主窗口:
  • 在主窗口空白处右键,添加一个垂直布局:
  • 保存.ui文件:

在项目的UI文件夹下新建forms\mainWindow两层目录,并将刚刚在designer中创建的.ui文件保存为mainWindow同名的mainWindow.ui文件:

designer中创建的mainWindow.ui文件,在pycharm中也可以打开:

它是一个 XML文件,文件描述了当前窗口以及窗口内所有控件的类名和特征以及从属关系,文件第一个widget class就是当前窗口的类名称,比如本例,它的窗口类是QMainWindow。

对应到designer:

三、用pyuic生成.py文件:

pycharm项目管理器,mainWindow.ui鼠标右键:

由于我在pycharm中的pyuic外部工具设置中的参数为:FileName -o FileNameWithoutExtension_ui.py

于是得到了mainWindow_ui.py文件:

我们来详细拆解一下这个用pyuic自动生成的mainWindow_ui.py文件:

python 复制代码
# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'mainWindow.ui'
##
## Created by: Qt User Interface Compiler version 6.6.3
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QMainWindow, QMenuBar, QPushButton,
    QSizePolicy, QStatusBar, QVBoxLayout, QWidget)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")

        self.verticalLayout.addWidget(self.pushButton)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 800, 21))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
    # retranslateUi

1、class Ui_MainWindow(object):

.py文件中定义了一个名为"Ui_MainWindow"的类(Ui_ 是 PyQt/PySide 的命名惯例,标识这是 "UI 界面类"),它继承于object类,(Python 3 中所有类默认隐式继承object,显式写出是为了兼容 / 规范)。

"Ui_MainWindow"中的"MainWindow"来自于ui文件中的主窗口的objectName,表示这是一个主窗口,当你在designer中把它改成别的名称,类名称"Ui_MainWindow"随之改变,不过一般不要改,除非你建立了一套属于自己的命名体系。

2、setupUi(self, MainWindow) 方法:

setupUi(self, MainWindow) 方法:核心方法,接收一个 MainWindow 实例作为参数,在该实例上创建 / 布局所有 UI 组件(如按钮、标签、菜单栏等);

3、retranslateUi(self, MainWindow) 方法:

用于多语言翻译,设置组件的文本 / 提示语。

  • 注意区分这里出现的几个MainWindow:

1、forms\mainWindow目录,是自己建的主窗口界面文件所在的目录,目录下的mainWindow.ui是自建的与目录同名的.ui文件。这个mainWindow可以改为自己需要的任何其他名称,比如masterWindow。

2、mainWindow.ui中的

python 复制代码
<widget class="QMainWindow" name="MainWindow">

这个项目的主窗口文件mainWindow.ui,它的QT类是QMainWindow,它的QT内部名称(objectName)是MainWindow(这个也可以自己改,比如改成masterForm)。

3、pyuic生成的mainWindow_ui.py文件中的

python 复制代码
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

class Ui_MainWindow:pyuic根据窗口的QT内部名称(objectName)自动生成的类名,前面加了Ui_,是 PyQt/PySide 的命名惯例,标识这是 "UI 界面类"。

def setupUi(self, MainWindow)中的MainWindow:MainWindow是本窗口的QT内部名称(objectName),这里表示接收一个MainWindow实例,并在这个实例上创建 / 布局所有 UI 组件。

我在初学的时候,被这几个名称搞得晕头转向,只有厘清它们的关系,才能实现一些高级应用,比如编写脚本实现项目的一键自动配置。

四、编写业务脚本

在mainWindow目录下新建同名.py文件:

mainWindow.py:

python 复制代码
import sys

from PySide6 import QtCore
from PySide6.QtWidgets import QMainWindow, QApplication
from mainWindow_ui import Ui_MainWindow

class mainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(mainWindow, self).__init__(parent)
        self.setupUi(self)   # 初始化界面
        self.run()  # 初始化完成后,运行一次界面,继续完成初始化设定
        self.pushButton.clicked.connect(self.on_pushButton_clicked)    # 绑定按钮点击事件

    def run(self):
        """
        初始化完成后,运行一次界面,继续完成初始化设定
        :return:
        """
        self.show()

        # 按钮点击事件的槽函数
    def on_pushButton_clicked(self):
        print("clicked")




if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = mainWindow()   # 创建主窗口实例对象
    sys.exit(app.exec())

至此,就完成了一个完整的"创建--转换--应用"UI界面的流程。

五、将UI项目与业务项目整合

UI(用户界面)的核心始终与 "用户需求、业务逻辑、系统生态、交互链路" 深度绑定,无法脱离关联场景而单独存在,UI 是业务逻辑的 "可视化载体",背后需依赖数据、功能模块、系统规则的支撑。比如:外卖 App 的 "订单跟踪页",界面上的 "商家接单 / 骑手取餐 / 配送中" 状态,依赖后端订单系统的实时数据同步;"取消订单" 按钮的显示 / 隐藏,依赖业务规则(如骑手已取餐则不可取消)------ 若脱离这些后台支撑,界面只是静态的 "空壳",无法响应真实业务流程。所以,只有将UI项目与业务项目深度整合,才有实用价值。

下面就简单创建一个完整的应用框架。

现在有这么一个需求:

在主窗口上有一个标签(QLabel),一个按钮(QPushButton),当点击按钮,获取当前的实时时间字符,把实时的时间字符送到一个作业函数内进行加工,返回:"当前时间:2025-12-xx xx:xx:xx,已处理完毕",然后在主窗口的标签上显示。

如图:

  • 实施步骤:

**1.**在项目根目录下创建main.py、UI_project.py,JOB目录下创建JOB.py

main.py

python 复制代码
# -*- coding: utf-8 -*-

###################################
# 这里是主函数
###################################

import sys

from UI_project import UiProj
from PySide6.QtWidgets import QApplication

def main():
    app = QApplication(sys.argv)
    UIPROJ = UiProj()  # 生成全局的ui项目对象
    sys.exit(app.exec())

if __name__ == '__main__':
    main()

UI_project.py:

python 复制代码
# -*- coding: utf-8 -*-
import time

###################################
# 这里定义项目级别的信号和变量、参数等
###################################

from PySide6.QtCore import Signal, QObject, Slot
from UI.forms.mainWindow.mainWindow import mainWindow  # 导入主窗口
from JOB.JOB import JOBPROJ   # 导入业务实例对象


# 定义全局的ui项目类
class UiProj(QObject):
    # 在这里定义全局信号
    # time_str_signal = Signal(str)   # 一个全局信号示例
    def __init__(self):
        super(UiProj, self).__init__()
        self.forms = []   # 一个全局的窗口列表,所有用到的窗口都在这里注册
        self.run()   # 初始化

    def run(self):
        """
        初始化
        :return:
        """
        self.add_forms()  # 添加窗口
        self.slot_signal()  # 连接全局的信号和槽函数
        self.variables()   # 初始化全局变量
        JOBPROJ.timeStr_job_out.emit("初始化显示内容")   # 初始化显示内容


    # 信号和槽函数
    def slot_signal(self):
        # 主窗口按钮点击事件的槽函数
        def on_MAINWINDOW_pushButton_clicked():
            self.time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())  # 获取当前时间字符串
            JOBPROJ.timeStr_job_in.emit(self.time_str)   # 使用业务信号跨窗口传递,把时间字符串传递给业务对象
        self.MAINWINDOW.pushButton.clicked.connect(on_MAINWINDOW_pushButton_clicked)  # 连接信号和槽函数

        # 业务对象完成工作后发出的信号的槽函数
        def on_JOB_timeStr_job_out(a_num):
            self.MAINWINDOW.label.setText(a_num)  # 使用业务信号跨窗口传递
        JOBPROJ.timeStr_job_out.connect(on_JOB_timeStr_job_out)   # 连接信号和槽函数

    # 全局变量
    def variables(self):
        self.time_str = ""          # 一个全局变量示例

    def add_forms(self):
        """
        添加窗口
        :return:
        """
        self.MAINWINDOW = mainWindow()   # 将主窗口实例化
        self.forms.append(self.MAINWINDOW)   # 将主窗口实例添加到窗口列表中

JOB.py

python 复制代码
# -*- coding: utf-8 -*-

###################################
# 这里定义业务处理项目
###################################

from PySide6.QtCore import QObject, Signal


class JobProj(QObject):
    timeStr_job_in = Signal(str)  # 定义一个业务信号,作用是接收时间字符串
    timeStr_job_out = Signal(str)  # 定义另一个业务信号,作用是发出时间字符串进行处理后的结果
    def __init__(self):
        super(JobProj, self).__init__()
        self.run()

    def run(self):   # 初始化
        self.slot_signal()   # 连接信号和槽函数


    def slot_signal(self):   # 连接信号和槽函数
        """
        连接信号和槽函数
        :return:
        """
        # 接收到时间字符串,进行作业的槽函数
        def on_timeStr_job_in(time_str):
            s = f"当前时间:{time_str},已处理完毕"  # 业务逻辑或作业内容
            self.timeStr_job_out.emit(s)  # 发送信号
        self.timeStr_job_in.connect(on_timeStr_job_in)    # 连接信号和槽函数

JOBPROJ = JobProj()   # 生成全局的业务实例对象
  1. 在QT designer中组态画面,并将其用pyuic转换成.py文件,在此基础上添加自定义代码,生成可供调用的.py文件。
复制代码
mainWindow.ui:(使用QT designer组态后得到的.ui文件)
html 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>644</width>
    <height>153</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item alignment="Qt::AlignmentFlag::AlignHCenter">
     <widget class="QLabel" name="label">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="minimumSize">
       <size>
        <width>80</width>
        <height>30</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
        <width>2000</width>
        <height>30</height>
       </size>
      </property>
      <property name="text">
       <string/>
      </property>
     </widget>
    </item>
    <item alignment="Qt::AlignmentFlag::AlignHCenter">
     <widget class="QPushButton" name="pushButton">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="minimumSize">
       <size>
        <width>80</width>
        <height>30</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
        <width>80</width>
        <height>30</height>
       </size>
      </property>
      <property name="text">
       <string>PushButton</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>644</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>
复制代码
mainWindow_ui.py:(自动生成,不要修改)
python 复制代码
# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'mainWindow.ui'
##
## Created by: Qt User Interface Compiler version 6.6.3
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QLabel, QMainWindow, QMenuBar,
    QPushButton, QSizePolicy, QStatusBar, QVBoxLayout,
    QWidget)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(644, 153)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.label = QLabel(self.centralwidget)
        self.label.setObjectName(u"label")
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
        self.label.setSizePolicy(sizePolicy)
        self.label.setMinimumSize(QSize(80, 30))
        self.label.setMaximumSize(QSize(2000, 30))

        self.verticalLayout.addWidget(self.label, 0, Qt.AlignmentFlag.AlignHCenter)

        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")
        sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
        sizePolicy1.setHorizontalStretch(0)
        sizePolicy1.setVerticalStretch(0)
        sizePolicy1.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
        self.pushButton.setSizePolicy(sizePolicy1)
        self.pushButton.setMinimumSize(QSize(80, 30))
        self.pushButton.setMaximumSize(QSize(80, 30))

        self.verticalLayout.addWidget(self.pushButton, 0, Qt.AlignmentFlag.AlignHCenter)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 644, 21))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.label.setText("")
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
    # retranslateUi
复制代码
mainWindow.py:
python 复制代码
import sys

from PySide6 import QtCore
from PySide6.QtWidgets import QMainWindow, QApplication
from . mainWindow_ui import Ui_MainWindow

class mainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(mainWindow, self).__init__(parent)
        self.setupUi(self)   # 初始化界面
        self.run()  # 初始化完成后,运行一次界面,继续完成初始化设定

    def run(self):
        """
        初始化完成后,运行一次界面,继续完成初始化设定
        :return:
        """
        self.show()

运行截图:

  1. 代码详解

在UI_project.py中,定义了一个名为UiProj的类,它继承于QObject,作为整个项目的主类。

QObject是Qt 核心基类,QObject具有以下特性:

  • 信号与槽(Signals & Slots):Qt 特有的跨对象通信机制,是 UI 交互、异步通知的核心;
  • 运行时类型信息(RTTI) :通过qobject_cast安全向下转型、metaObject()获取类元信息;
  • 属性系统(Q_PROPERTY):定义可被 Qt 反射、绑定的属性,支持 UI 与数据联动;
  • 继承体系: 子类可通过setParent()建立父子关系,父对象销毁时自动销毁所有子对象(避免内存泄漏);
  • 支持对象名称:setObjectName()/objectName()),常用于 UI 控件查找;
  • 可拦截 / 处理 Qt 事件: 内置事件处理(event())、事件过滤器(installEventFilter()),可拦截 / 处理 Qt 事件;

在UiProj类中,导入了所有的窗口的.py文件(在pyuic转换成.py文件基础上添加自定义代码,生成可供调用的.py文件)并将其实例化。

在UiProj类中,还导入了业务处理类并将其实例化。UiProj类是项目中用于处理业务的类,同样继承于QObject。

由于UiProj类中实例化了所有窗口类以及业务处理类,那么所有的窗口构件以及构件的操作信号和和显示参数,还有所有的业务处理函数,在这里都是互通的,这样就实现了全局层面的信号操传递。

比如本例的信号传递过程:

主窗口按钮点击,将当前时间字符串交给JOBPROJ.timeStr_job_in这个信号去发射,JOBPROJ.timeStr_job_in信号是业务处理类(JOB.JobProj)中的一个信号,作用是接收输入的字符串,并连接业务处理槽函数对字符串进行处理,然后将处理结果交给timeStr_job_out信号去发射,而timeStr_job_out信号连接的槽函数,是将主窗口中的标签文字更新,这样就完成了一个信号传递过程。为什么不将业务处理槽函数放在主窗口的.py文件中呢?是因为这样做可以做到画面和功能的彻底解耦、前后端的彻底分离,方便项目的编程、修改和移植。显而易见的是:如果将本例按钮点击传递的信号换成一个图片文件,业务处理槽函数换成YOLO的预测函数,那么槽函数的返回结果就是YOLO的预测结果,将其作为信号发射回主画面并显示,这就是大多数YOLO预测项目的信号流程了。

说干就干,把业务功能换成YOLO的预测,当点击主窗口的按钮,会将一个图片地址传递给YOLO,并将预测结果的第一个显示在主窗口的标签。

新增文件:猫的图片cat.jpg,yolo预训练模型yolo11n.pt

复制代码
UI_project.py:
python 复制代码
# -*- coding: utf-8 -*-
import time

###################################
# 这里定义项目级别的信号和变量、参数等
###################################

from PySide6.QtCore import Signal, QObject, Slot
from UI.forms.mainWindow.mainWindow import mainWindow  # 导入主窗口
from JOB.JOB import JobProj   # 导入业务处理类


# 定义全局的ui项目类
class UiProj(QObject):
    def __init__(self):
        super(UiProj, self).__init__()
        self.forms = []   # 一个全局的窗口列表,所有用到的窗口都在这里注册
        self.run()   # 初始化

    def run(self):
        """
        初始化
        :return:
        """
        self.add_forms()  # 添加窗口
        self.JOBPROJ = JobProj()  # 生成全局的业务处理实例对象
        self.slot_signal()  # 连接全局的信号和槽函数
        self.variables()   # 初始化全局变量


    # 信号和槽函数
    def slot_signal(self):
        # 主窗口按钮点击事件的槽函数
        def on_MAINWINDOW_pushButton_clicked():
            self.JOBPROJ.img_job_in.emit(r"cat.jpg")   # 使用业务信号跨窗口传递,把图片地址传递给业务对象
        self.MAINWINDOW.pushButton.clicked.connect(on_MAINWINDOW_pushButton_clicked)  # 连接信号和槽函数

        # 业务对象完成工作后发出的信号的槽函数
        def on_JOB_timeStr_job_out(cls_name, conf):
            self.MAINWINDOW.label.setText(f"预测结果:{cls_name},置信度:{float(conf):.3f}")  # 使用业务信号跨窗口传递
        self.JOBPROJ.predict_job_out.connect(on_JOB_timeStr_job_out)   # 连接信号和槽函数


    # 全局变量
    def variables(self):
        self.time_str = ""          # 一个全局变量示例

    def add_forms(self):
        """
        添加窗口
        :return:
        """
        self.MAINWINDOW = mainWindow()   # 将主窗口实例化
        self.forms.append(self.MAINWINDOW)   # 将主窗口实例添加到窗口列表中
复制代码
JOB.py:
python 复制代码
# -*- coding: utf-8 -*-

###################################
# 这里定义业务处理项目
###################################

from PySide6.QtCore import QObject, Signal
from ultralytics import YOLO


class JobProj(QObject):
    """
    业务处理类
    """
    img_job_in = Signal(str)  # 定义一个业务信号,作用是接收时间字符串
    predict_job_out = Signal(str, float)  # 定义另一个业务信号,作用是发出时间字符串进行处理后的结果
    def __init__(self):
        super(JobProj, self).__init__()
        self.run()

    def run(self):   # 初始化
        self.model = YOLO("../yolo11n.pt")
        self.slot_signal()   # 连接信号和槽函数


    def slot_signal(self):   # 连接信号和槽函数
        """
        连接信号和槽函数
        :return:
        """
        # 接收到时间字符串,进行作业的槽函数
        def on_img_job_in(img_path):
            results = self.model.predict(
                source=img_path,
                conf=0.25,  # 置信度阈值,只显示置信度>0.25的目标
                iou=0.45,  # NMS去重阈值
                imgsz=640,  # 推理图片尺寸
                device="cpu",  # 使用CPU推理(如需GPU改为"0")
                show_labels=True,  # 显示标签
                show_conf=True,  # 显示置信度
                save=False  # 先不保存,后续自定义保存
            )
            first_box = results[0].boxes[0]  # 获取第一个检测框
            cls_id = int(first_box.cls[0])  # cls是张量,取第一个元素并转int
            cls_name = self.model.names[cls_id]  # 类别名称
            conf = float(first_box.conf[0])  # 置信度
            bbox = first_box.xyxy[0].tolist()  # 边界框坐标 [x1,y1,x2,y2]

            print(f"第一个检测目标:")
            print(f"  类别ID:{cls_id}")
            print(f"  类别名称:{cls_name}")
            print(f"  置信度:{conf}")
            print(f"  边界框:{bbox}")
            self.predict_job_out.emit(cls_name, conf)  # 发送信号
        self.img_job_in.connect(on_img_job_in)    # 连接信号和槽函数
复制代码
mainWindow.py:
python 复制代码
import sys

from PySide6 import QtCore
from PySide6.QtWidgets import QMainWindow, QApplication
from . mainWindow_ui import Ui_MainWindow

class mainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(mainWindow, self).__init__(parent)
        self.setupUi(self)   # 初始化界面
        self.run()  # 初始化完成后,运行一次界面,继续完成初始化设定

    def run(self):
        """
        初始化完成后,运行一次界面,继续完成初始化设定
        :return:
        """
        self.label.setText("点击按钮预测")
        self.show()

别的不变。

当然了,只是一个极简的基本框架,还要加上线程管理、数据库管理、用户管理等等。

相关推荐
Echo_NGC22372 小时前
【传统JSCC+Deep JSCC】联合信源信道编码完全指南
人工智能·python·深度学习·神经网络·conda·无人机·jscc
东方佑2 小时前
使用Python标准库将Word文档转换为HTML:深入解析.docx文件处理脚本
python·html·word
Blossom.1182 小时前
大模型AI Agent实战:ReAct框架从零实现与金融研报分析系统
人工智能·学习·react.js·stable diffusion·金融·aigc·知识图谱
祁思妙想2 小时前
Python中CORS 跨域中间件的配置和作用原理
开发语言·python·中间件
其美杰布-富贵-李2 小时前
数据清理与特征工程完整指南
笔记·深度学习·特征工程·训练·数据清理
与遨游于天地2 小时前
深入了解 Java `synchronized`:从对象头到锁升级、线程竞争感知
java·开发语言·c#
老王熬夜敲代码2 小时前
计算机网络--IP概念
linux·网络·笔记
yongui478342 小时前
基于C# WinForm开发的固定资产管理系统
开发语言·c#