使用QPushButton与QLabel组件实现一个简单的批量图像浏览

描述

引言

基于前面几篇文章介绍的知识点,使用QPushButton与QLabel组件结合水平与垂直布局管理器,实现一个简单的批量图像浏览,支持图像文件夹选择、按钮信号触发与槽函数响应、支持上一张、下一张图像浏览,实现一个最简化版本的图像浏览器

垂直与水平布局混合使用

PyQT5中的QWidget对象支持嵌套方式,在一个QWidget中可以支持多个子QWidget对象,每个QWidget都有自己的布局方式,这样通过多重QWidget嵌套与叠加就可以实现复杂界面设计。在我开发OpenMV工具软件过程中,多数子界面都是通过水平跟垂直布局嵌入实现的界面设计。这样做的好处是避免使用绝对定位方式布局组件元素导致不同分辨率的显示差异与用户体验不一致。

openMV

上图中第一行有三个组元素,两个QLabel,分别显示当前文件路径与文件夹总图像数目;一个按钮实现图像文件夹选择功能,三个组件元素在一个子QWidget对象(panel1)中通过水平布局方式(QHBoxLayout)从左到右排列。

内置图标ICON使用

PyQT5的QStyle支持内置图标ICON支持,支持常见应用程序开发所需要的图标,直接使用这些图标可以省去很多麻烦。支持的图标列表请看下图说明:

openMV

采用下面的相似代码即可获取需要的ICON图标使用。  

 

back_pix = QtWidgets.QStyle.SP_ArrowBack
back_icon = self.style().standardIcon(back_pix)
图表文件名称列表如下:

 

openMV

中间是一个QLabel组件实现图像显示与更新功能   最后一行基于PyQT5的QStyle中内置图标引用实现了两个ICON按钮功能,支持Tooltip提示功能,分别实现显示上一张与下一张图像切换显示功能。两个ICON按钮通过水平布局方式同样放在一个QWidget对象(panel2)中。  

最终把panel1、imageLabel、panel2三个子元素通过垂直布局(QVBoxLayout)添加到自定义的QWidget对象-ImageBrowserPanel。  

最后在主程序中初始化ImageBrowserPanel对象实例,设置为QMainWindow的CenteralWidget即可完成。

按钮信号与响应

三个按钮分别完成图像文件夹选择、上一张更新显示、下一张更新显示。默认选择图像文件夹之后会显示该文件夹中第一张图像,同时更新文件显示QLabel上显示信息与imageLabel上显示的图像内容。

运行演示与代码

运行结果演示:

openMV

主面板界面类代码如下:

 


class ImageBrowserPanel(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.image_files = []
        self.current_index = -1
        # 文本标签
        self.pathLabel = QtWidgets.QLabel()
        self.pathLabel.setText("文件名称: test.png")
        self.pathLabel.setStyleSheet("background-color:deeppink; color: blue; border-radius:5px")
        self.pathLabel.setAlignment(QtCore.Qt.AlignCenter)
        # 图像总数
        self.numLabel = QtWidgets.QLabel()
        self.numLabel.setText("图像总数: 0")
        self.pathLabel.setStyleSheet("background-color:deeppink; color: blue; border-radius:5px")
        self.numLabel.setAlignment(QtCore.Qt.AlignCenter)


        fileBtn = QtWidgets.QPushButton("选择...")
        hbox_layout = QtWidgets.QHBoxLayout()
        hbox_layout.addWidget(self.pathLabel)
        hbox_layout.addWidget(self.numLabel)
        hbox_layout.addWidget(fileBtn)
        hbox_layout.addStretch(1)
        panel1 = QtWidgets.QGroupBox("图像信息")
        panel1.setLayout(hbox_layout)


        # 图像标签
        self.imgLabel = QtWidgets.QLabel()
        pixmap = QtGui.QPixmap("test3.png")
        pix = pixmap.scaled(QtCore.QSize(620, 500), QtCore.Qt.KeepAspectRatio)
        self.imgLabel.setPixmap(pix)
        self.imgLabel.setAlignment(QtCore.Qt.AlignCenter)


        # 左右浏览
        back_pix = QtWidgets.QStyle.SP_ArrowBack
        back_icon = self.style().standardIcon(back_pix)


        forward_pix = QtWidgets.QStyle.SP_ArrowForward
        forward_icon = self.style().standardIcon(forward_pix)


        backBtn = QtWidgets.QPushButton(back_icon, "")
        backBtn.setIconSize(QtCore.QSize(48, 48))
        backBtn.setToolTip("上一张")


        forwardBtn = QtWidgets.QPushButton(forward_icon, "")
        forwardBtn.setIconSize(QtCore.QSize(48, 48))
        forwardBtn.setToolTip("下一张")


        panel2 = QtWidgets.QWidget()
        hbox_layout2 = QtWidgets.QHBoxLayout()
        hbox_layout2.addWidget(backBtn)
        hbox_layout2.addWidget(forwardBtn)
        panel2.setLayout(hbox_layout2)


        # 添加到布局管理器中
        vbox_layout = QtWidgets.QVBoxLayout()
        vbox_layout.addWidget(panel1)
        vbox_layout.addWidget(self.imgLabel)
        vbox_layout.addWidget(panel2)
        vbox_layout.addStretch(1)


        # 面板容器
        self.setLayout(vbox_layout)


        # setup listener
        fileBtn.clicked.connect(self.on_select_image_dir)
        backBtn.clicked.connect(self.on_back_image_view)
        forwardBtn.clicked.connect(self.on_forward_image_view)


    def on_back_image_view(self):
        if self.current_index > 0:
            self.current_index = self.current_index - 1
            filename = self.image_files[self.current_index]
            self.pathLabel.setText("文件名称: " + filename)
            print(filename)
            pixmap = QtGui.QPixmap(filename)
            pix = pixmap.scaled(QtCore.QSize(620, 500), QtCore.Qt.KeepAspectRatio)
            self.imgLabel.setPixmap(pix)


    def on_forward_image_view(self):
        last = len(self.image_files) - 1
        if self.current_index < last:
            self.current_index = self.current_index + 1
            filename = self.image_files[self.current_index]
            self.pathLabel.setText("文件名称: " + filename)
            print(filename)
            pixmap = QtGui.QPixmap(filename)
            pix = pixmap.scaled(QtCore.QSize(620, 500), QtCore.Qt.KeepAspectRatio)
            self.imgLabel.setPixmap(pix)


    def on_select_image_dir(self):
        img_dir = QtWidgets.QFileDialog.getExistingDirectory(self, "图像文件夹", ".")
        files = os.listdir(img_dir)
        self.image_files.clear()
        self.current_index = -1
        for f in files:
            if f.endswith(".png") or f.endswith(".jpg") or f.endswith(".bmp"):
                self.image_files.append(os.path.join(img_dir, f))
        if len(self.image_files) > 0:
            self.current_index = 0
            filename = self.image_files[0]
            print(filename)
            self.pathLabel.setText("文件名称: " + filename)
            self.numLabel.setText("图像总数: " + str(len(self.image_files)))
            pixmap = QtGui.QPixmap(filename)
            pix = pixmap.scaled(QtCore.QSize(620, 500), QtCore.Qt.KeepAspectRatio)
            self.imgLabel.setPixmap(pix)
上述代码演示了如何打开文件夹,遍历图像文件、如何更新QLabel上显示的图像与文字信息,如何构建一个自定义的QWidget对象。  

QApplication应用程序代码如下:

# 初始化APP实例
app = QtWidgets.QApplication(sys.argv)
# 初始化桌面容器
main_win = QtWidgets.QMainWindow()
# 设置APP窗口名称
main_win.setWindowTitle("PyQT5图像浏览器-2号高手")
# 初始化内容面板
content_panel = ImageBrowserPanel()
# 设置窗口大小
main_win.setMinimumSize(640, 500)
main_win.setCentralWidget(content_panel)


# 请求显示
main_win.show()
# 加载窗口并启动App
app.exec()

 

运行结果如下:

openMV 总结

本文主要是演示了PyQT5中水平与垂直布局组合,多个QWidget组件嵌套使用排版,按钮事件触发与槽函数更新UI组件的各种PyQT5基本编程技能与技巧。







审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分