PyQt---基本界面设计【附代码】

Qt是GUI开发中的一个工具,可以根据用户需求进行程序界面的开发。Qt的开发有C++版的和python版的,不论你有哪种编程语言的基础都很好上手学习。PyQt5是Qt框架的Python语言实现,也是本文将要介绍的,并将会建立一个PyQt专栏不断更新供大家学习。


环境说明

在使用PyQt前需要确保你以安装相关安装包:

qt5-applications:5.15.2.2.3

qt5-tools            :5.15.2.1.3

QtPy                  :2.1.0

PyQt5                 :5.15.9
pyqt5-plugins      :5.15.9.2.3
PyQt5-Qt5           :5.15.2
PyQt5-sip            :12.11.0
pyqt5-tools           :5.15.9.3.3


Qt开发大致可以有两种方法:

1.直接用代码设计界面和控件;

2.用Qt designer 设计布局和控件,再用代码实现具体方法;

在本文中将进行一个简单的示例来让大家了解和入手PyQt5。比如我们要实现一个这样的界面,可以加载图片和加载torch模型的GUI。

1.直接用代码设计布局

我们需要import以下包

from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QTextBrowser, QWidget, QLabel, QPushButton, QFileDialog

其中QImage、QPixmap是和图像处理有关的类;

QApplication用于创建应用程序对象,有且仅有一个【放在main函数中】;

QWidget是窗口类,可以创建一个空白的窗口;

QTextBrowser,QLabel,QPushButton等均是控件;

我们现在需要实现一个自己的界面(窗口),需要继承QWidget,代码如下:

继承QWidget父类,并调用父类的构造函数初始化,self.initUI()是我们接下来定义的一些初始化参数和方法。

class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.initUI()

在我们的Widget中,我们需要设定以下界面大小为[640,480],给窗口起一个名字。 

    def initUI(self):
        # 初始化标题,界面大小
        self.resize(640, 480)
        # 窗口名称
        self.setWindowTitle('my first widget')

创建我们的第一个控件text_browser,我们需要实例化对象QTextBrowser。move函数指的是把改控件移动到哪里,resize是该控件的大小,并且可以用setText设置里面的初始化文本信息。

        # 创建文本浏览器对象,self指的是在当前widget添加显示
        self.text_browser = QTextBrowser(self)
        self.text_browser.move(10, 10)
        self.text_browser.resize(620, 30)
        self.text_browser.setText("The Hello World Before!")

那么此时得到的界面如下: 

 

然后我们插入一个控件用来显示图像,这里我用的是QLabel。下面的代码是用QLabel进行相关属性的设置,我们这里将该控件的背景设置为白色,大小为300x300,该控件的名称为"image_show"。

        # 定义图片标签大小(显示图像大小)
        self.label_h = 300
        self.label_w = 300
        self.label_show_camera = QLabel(self)
        self.label_show_camera.move(10, 50)
        # 设置Qlabel窗口大小
        self.label_show_camera.setFixedSize(self.label_w, self.label_h)
        self.label_show_camera.setText("TextLabel")
        # Qlalbel的背景变为白色
        self.label_show_camera.setStyleSheet("QLabel{background:white;}")
        # 设置标签对象的名称
        self.label_show_camera.setObjectName("image_show")

然后将图像在上述的Qlabel中进行显示。 

        show = Image.open("../dog.jpg").convert("RGB")
        show = show.resize([self.label_w, self.label_h])
        showImage = QImage(np.array(show), np.shape(show)[1], np.shape(show)[0], QImage.Format_RGB888)
        # 设置图像
        self.label_show_camera.setPixmap(QPixmap.fromImage(showImage))

接下来我们可以创建一个按钮,通过点击该按钮实现加载模型的功能。这里其实有个比较专业化的术语,叫信号和槽,在Qt中我们要实现类似点击并调用某功能的实现,这个过程包含:信号的发送者(按钮),发送的具体信号(点击),信号的接受者(显示的界面),信号处理(槽)(处理你定义的函数)。

我们先创建一个按钮(信号的发送者),实例化QPushButton即可,self就是本Widget窗口,和c++中的this指针类似。

        # 创建按钮对象
        self.load_model_button = QPushButton('load model', self)
        self.load_model_button.move(350, 350)

然后我们定义一个槽函数,该槽函数是通过点击按钮后加载模型并在text_browser控件中显示加载成功。代码如下:

    # 槽函数
    def load_model(self):
        # 打开文件对话框以选择模型文件
        file_path, _ = QFileDialog.getOpenFileNames(self, 'Choose a model file', '', 'Torch Model Files (*.pth)')

        # 如果用户选择了文件
        if file_path:
            print(file_path)
            ckpt = torch.load(file_path[0], 'cuda')
            result = "Model loaded successfully"
            # 更新界面上的结果标签
            self.text_browser.setText(result)
            print("Selected model file:", file_path)

建立号槽函数以后就可以建立这个信号连接了,代码如下:

        # 创建按钮对象
        self.load_model_button = QPushButton('load model', self)
        self.load_model_button.move(350, 350)
        self.load_model_button.clicked.connect(self.load_model)

        self.show()

最终界面如下:

可以看到加载模型后上面的窗口显示为加载成功。

 

完整代码如下:

import sys

from PIL import Image
import numpy as np
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QTextBrowser, QWidget, QLabel, QPushButton, QFileDialog
import torch


class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.initUI()

    def initUI(self):
        # 初始化标题,界面大小
        self.resize(640, 480)
        # 窗口名称
        self.setWindowTitle('my first widget')
        # 创建文本浏览器对象,self指的是在当前widget添加显示
        self.text_browser = QTextBrowser(self)
        self.text_browser.move(10, 10)
        self.text_browser.resize(620, 30)
        self.text_browser.setText("The Hello World Before!")

        # 定义图片标签大小(显示图像大小)
        self.label_h = 300
        self.label_w = 300
        self.label_show_camera = QLabel(self)
        self.label_show_camera.move(10, 50)
        # 设置Qlabel窗口大小
        self.label_show_camera.setFixedSize(self.label_w, self.label_h)
        self.label_show_camera.setText("TextLabel")
        # Qlalbel的背景变为白色
        self.label_show_camera.setStyleSheet("QLabel{background:white;}")
        # 设置标签对象的名称
        self.label_show_camera.setObjectName("image_show")

        show = Image.open("../dog.jpg").convert("RGB")
        show = show.resize([self.label_w, self.label_h])
        showImage = QImage(np.array(show), np.shape(show)[1], np.shape(show)[0], QImage.Format_RGB888)
        # 设置图像
        self.label_show_camera.setPixmap(QPixmap.fromImage(showImage))

        # 创建按钮对象
        self.load_model_button = QPushButton('load model', self)
        self.load_model_button.move(350, 350)
        self.load_model_button.clicked.connect(self.load_model)

        self.show()

    # 槽函数
    def load_model(self):
        # 打开文件对话框以选择模型文件
        file_path, _ = QFileDialog.getOpenFileNames(self, 'Choose a model file', '', 'Torch Model Files (*.pth)')

        # 如果用户选择了文件
        if file_path:
            print(file_path)
            ckpt = torch.load(file_path[0], 'cuda')
            result = "Model loaded successfully"
            # 更新界面上的结果标签
            self.text_browser.setText(result)
            print("Selected model file:", file_path)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyWidget()
    sys.exit(app.exec_())


2.Qt designer界面设计

该方法需要用到designer工具,方法也很简单,只要你环境配置正确,然后在你的python环境下找的designer.exe即可,一般位置在你python环境/lib/site-packages/qt5-applictions/Qt/bin/

双击打开后界面如下:

 

先来说一下为什么推荐这种方法,直接用代码设计布局需要你在写的时候脑子里就要有布局的基础设计图,然后自己去设置每个控件、画面的大小和位置,这是很不方便的。而用designer可以先把大概的布局、位置等设置出来,然后在实现其他细节的时候直接调用控件使用即可。

创建一个Main Window。可以为用户提供主窗口的程序类。然后我们可以在左侧的工具栏拖入我们要的控件即可。

怎么设计就因人而异了,这里我只列出我用到的。

我这里设置了两QLabel用于显示图像和模型结构,并设置该布局为水平布局【设置布局,随着拖动窗口大小,控件也会相对应的缩放】。

然后设置两个按钮用于加载图像和加载模型。界面如下:

直接双击控件就可以输入文字。需要注意的是,我们在插入每个控件的时候,最后是给每个控件添加对象名,该对象名用于后续在代码中调用。例如我这里给两个Label设置对象名如下:

然后右侧的属性编辑器是可以设置控件属性用的:

 

例如将show image这个控件背景色变为白色【默认是透明的】。点击该控件,在右侧的属性编辑器->QWidget->styleSheet设置颜色即可。

同时在 属性编辑器->QLabel->scaledContents打上勾,不然显示的图像非常小,打勾后显示的图像会缩放到控件大小。

设计好以后保存该ui到你的python项目中

 然后加载在python中直接加载我们的ui文件。

# 加载UI文件
Ui_widget, _ = uic.loadUiType('myui.ui')

然后我们就可以用继续用代码实现UI界面中的各个功能了。实现方法也很简单,直接调用控件对象名作为属性即可。如下:

需要继承QMainWindow和Ui_widget。然后里面的self.load_model_button就是前面控件所设置的对象名

import torch
from PyQt5 import uic
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QWidget, QFileDialog, QApplication, QMainWindow
from PIL import Image
import numpy as np
import sys

# 加载UI文件
Ui_widget, _ = uic.loadUiType('myui.ui')

class MyWidget(QMainWindow, Ui_widget):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.load_model_button.clicked.connect(self.load_model)
        self.load_image_button.clicked.connect(self.load_image)
        self.show_window_width = self.show_image_window.width()
        self.show_window_height = self.show_image_window.height()
        self.show()

 最终的界面和效果如下:

相对应的代码如下:

# E:\ProgramData\Anaconda3\envs\pytorch1.7\Lib\site-packages\qt5_applications\Qt\bin
import torch
from PyQt5 import uic
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QWidget, QFileDialog, QApplication, QMainWindow
from PIL import Image
import numpy as np
import sys

# 加载UI文件
Ui_widget, _ = uic.loadUiType('myui.ui')


class MyWidget(QMainWindow, Ui_widget):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.load_model_button.clicked.connect(self.load_model)
        self.load_image_button.clicked.connect(self.load_image)
        self.show_window_width = self.show_image_window.width()
        self.show_window_height = self.show_image_window.height()
        self.show()

    def load_image(self):
        image_path, _ = QFileDialog.getOpenFileNames(self, 'Choose a image file', '', 'image files (*.jpg)')
        if image_path:
            img = Image.open(image_path[0]).convert("RGB")
            #img = img.resize([self.show_window_width, self.show_window_height])
            showImage = QImage(np.array(img), np.shape(img)[1], np.shape(img)[0], QImage.Format_RGB888)
            # 设置图像
            self.show_image_window.setPixmap(QPixmap.fromImage(showImage))



    def load_model(self):
        # 打开文件对话框以选择模型文件
        file_path, _ = QFileDialog.getOpenFileNames(self, 'Choose a model file', '', 'Torch Model Files (*.pth)')

        # 如果用户选择了文件
        if file_path:
            print(file_path)
            ckpt = torch.load(file_path[0], 'cuda')
            result = "Model loaded successfully"
            print(result)
            print("Selected model file:", file_path)
            # 模型结构输出到show_model_keys中
            keys = '\n'.join(ckpt.keys())
            self.show_model_window.setText(keys)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyWidget()
    sys.exit(app.exec_())

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决亚马逊,速卖通,eBay买家账号关联问题,提高下单成功率

做自养号测评、补单首先要解决的就是安全性的问题,如果安全性解决的不了的话,其他的都不要再提了 让我们了解一下市面上的IP及可能遇到的问题。 目前,常见的IP包括luminati、googelfi、922、TM流量卡和Rola,Rrocks专线等。主要问…

在做题中学习(31):电话号码的字母组合(全排列)

17. 电话号码的字母组合 - 力扣(LeetCode) 思路:既然要排列组合,就得先根据数字字符取出来 所以先定义一个string类的数组通过下标取到每个数字对应的映射。 string _numsTostr[10]{"","","abc"…

医学多模态模型总结(一)

概念 医学多模态大模型是指利用多种不同的医学数据源和模型,通过深度学习和人工智能技术,构建一个综合性的大型模型,以实现更加准确和全面的医学数据分析和预测。 这种模型可以同时处理多种医学数据类型,如医学图像、病历文本、…

应用在LED灯光控制触摸屏中的触摸芯片

LED灯光控制触摸屏方法,包括:建立触摸屏的触摸轨迹信息与LED灯光驱动程序的映射关系;检测用户施加在触摸屏上的触摸轨迹,生成触摸轨迹信息;根据生成的触摸轨迹信息,调用对应的LED灯光驱动程序,控…

HTML 块级元素与行内元素有哪些以及注意、总结

行内元素和块级元素是HTML中的两种元素类型,它们在页面中的显示方式和行为有所不同。 块级元素(Block-level Elements): 常见的块级元素有div、p、h1-h6、ul、ol、li、table、form等。 块级元素会独占一行,即使没有…

web服务器之——搭建两个基于不同端口访问的网站

要求如下: 建立一个使用web服务器默认端口的网站,设置DocumentRoot为/www/port/80,网页内容为:the port is 80。建立一个使用10000端口的网站,设置DocumentRoot为/www/port/10000,网页内容为:t…

太阳能光伏企业网站建设效果如何

光伏行业近些年发展也比较迅速,其服务/产品拓展度较高,对企业来说,合作商较少更需要多地域寻找目标客户及信息承载展示、拓展等,传统线下方式单一且不足,线上成为众商家经营的方向。 1、品牌宣传、信息呈现难 太阳能…

windows 镜像下载地址

HelloWindows.cn - 精校 完整 极致 Windows系统下载仓储站

原来使用代码也可以画时序图,用这个Mermaid就行,真香

本文首发于我的个人掘金博客,看到很多人都比较喜欢这篇文章,分享给大家。 个人博客主页:https://www.aijavapro.cn 个人掘金主页:juejin.cn/user/2359988032644541/posts 个人知识星球: 觉醒的新世界程序员 一、背景 在软件开发和…

数据结构基础介绍

一.起源及重要性 1968 年,美国的高德纳 Donakl E . Kn uth 教授在其所写的《 计算机程序艺术》第一卷《基本算法 》 中,较系统地阐述了数据的逻辑结构和存储结构及其操作, 开创了数据结构的课程体系 ,数据结构作为一门独立的…

记录一次postgresql临时表丢失问题

项目相关技术栈 springboot hikari连接池pgbouncerpostgresql数据库 背景 为了优化一个任务执行的速度,我将任务的sql中部分语句抽出生成临时表(create temp table tempqw as xxxxxxxxx),再和其他表关联,提高查询速…

php之jwt使用

PHP JWT(JSON Web Token)是一种用于身份验证和授权的开放标准。JWT是一个包含有关用户或实体身份信息的安全令牌,它由三部分组成:头部(Header)、载荷(Payload)和签名(Sig…

Linux上进行Nacos安装

Nacos安装指南 仅供参考,若有错误,欢迎批评指正! 后期会继续上传docker安装nacos的过程! 1.Windows安装 开发阶段采用单机安装即可。 1.1.下载安装包 在Nacos的GitHub页面,提供有下载链接,可以下载编译好…

PyTorch张量:内存布局

你可能对 torch 上的某些函数感到困惑,它们执行相同的操作但名称不同。 例如: reshape()、view()、permute()、transpose() 等。 这些函数的做法真的不同吗? 不! 但为了理解它,我们首先需要了解一下张量在 pytorch 中…

Http模块

Http模块 1.创建http服务 //导入http模块 const http require(http)//创建服务对象 const server http.createServer((request,response)>{response.end(Hello HTTP Server) })// 监听端口,启动服务 server.listen(9000,()>{console.log(服务已启动....);…

【Jeecg Boot 3 - 第二天】2.1、nginx 部署 JEECGBOOT VUE3

一、场景 二、实战 ▶ 2.1、打包(build 前端) > Stage 1:修改配置文件 .env.production(作用:指向后端接口地址) > Stage 2:点击build(作用&#xff1…

智能优化算法应用:基于蝙蝠算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于蝙蝠算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于蝙蝠算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蝙蝠算法4.实验参数设定5.算法结果6.参考文献7.MA…

HeartBeat监控Redis状态

目录 一、概述 二、 安装部署 三、配置 四、启动服务 五、查看数据 一、概述 使用heartbeat可以实现在kibana界面对redis服务存活状态进行观察,如有必要,也可在服务宕机后立即向相关人员发送邮件通知 二、 安装部署 参照文章:HeartBeat监…

「差生文具多系列」推荐两个好看的 Redis 客户端

📢 声明: 🍄 大家好,我是风筝 🌍 作者主页:【古时的风筝CSDN主页】。 ⚠️ 本文目的为个人学习记录及知识分享。如果有什么不正确、不严谨的地方请及时指正,不胜感激。 直达博主:「…

前端 三种解决跨域问题 jsonp 、CORS、代理服务器 解决跨域全家桶

我的报错情况是 后端接口是3000 前端本地接口是8080,最后出现跨域 1.什么是跨域? 首先跨域是一种安全机制,是在开发上线前考虑到的安全问题并且需要采取合适的手段去避免这个问题带来的程序错误,接口跨域可以后端处理,也可以前端处理&#x…