美文网首页
PyQt5实现一个检测界面

PyQt5实现一个检测界面

作者: Yah_da | 来源:发表于2021-03-17 23:12 被阅读0次

界面设计

根据功能,将主窗口分为4个区,点击原图/结果图,用子窗口显示放大图。


主窗口设计 自窗口设计

实现效果

主窗口
  • 一张检测:
    1)选择图片,上传待检测原图
    2)检测,(运行检测网络,延迟约0.5s,)显示结果图

  • 批量检测:
    1)选择文件夹,显示文件夹名,并显示文件夹下第一张图
    2)开始检测,(运行检测网络,延迟约5s,)显示第一张图对应的结果图
    3)下一张,显示下一张图,并显示对应的结果图

子窗口

环境安装

pip install PyQt5
pip install PyQt5-tools

export QT_DEBUG_PLUGINS=1
sudo apt install --reinstall libxcb-xinerama0

安装注意:libxcb-xinerama

关键代码

自定义控件

class MyQLabel(QLabel):
    clicked_signal = pyqtSignal()  # 自定义信号, 信号必须为类属性

    def __init__(self, parent=None):
        super(MyQLabel, self).__init__(parent)

    def mouseReleaseEvent(self, QMouseEvent):  # overrides,鼠标松开时调用
        self.clicked_signal.emit()  # 发

    def myConnectSlot(self, outFunc):  # 可在外部与槽函数连接 public
        self.clicked_signal.connect(outFunc)


class MyThread(QThread):
    sinOut = pyqtSignal()

    def __init__(self):
        super(MyThread, self).__init__()

    def run(self):  # 当线程启动时,执行run函数
        self.sleep(5)
        self.sinOut.emit()

主窗口

import sys
import os
import time
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Main(QWidget):
    def __init__(self):
        super().__init__()

        # 变量
        self.str_path_ori = ""
        self.str_path_res = ""
        self.str_dir_ori = ""
        self.list_imgs = []
        self.list_imgs_inx = 0
        self.child_window = Child()
        self.child_window2 = Child()
        self.thread = MyThread()

        # 主窗口属性
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.left = (screen.width() - size.width()) // 2
        self.top = (screen.height() - size.height()) // 2
        self.height = int(QApplication.desktop().height() * 0.9)
        self.width = self.height * 16 // 9
        self.title = '舰船检测'

        self.initUI()

    def show_child(self):
        # original image
        self.child_window.showMaximized(self.str_path_ori)

    def show_child2(self):
        # result image
        self.child_window2.showMaximized(self.str_path_res)

    def initUI(self):
        self.setWindowTitle(self.title)
        self.move(self.left, self.top)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        # self.statusBar().showMessage('1、选择图片  2、检测')

        # left
        self.ori_label = QLabel("原图:")
        self.pic_ori_label = MyQLabel(QLabel(self))  # 显示原图
        self.res_label = QLabel("检测结果:")
        self.pic_res_label = MyQLabel(QLabel(self))  # 显示结果图
        # right
        self.file_btn = QPushButton('(一张)选择图片', self)
        self.files_btn = QPushButton('(批量)选择文件夹', self)
        self.run_btn = QPushButton('(一张)检测', self)
        self.runs_btn = QPushButton('(批量)开始检测', self)
        self.path_label = QLabel(self)
        self.next_btn = QPushButton('下一张', self)

        self.all_h_layout = QHBoxLayout()  # horizontal水平
        self.left_v_layout = QVBoxLayout()
        self.right_v_layout = QVBoxLayout()
        self.btn_v_layout = QVBoxLayout()  # button
        self.para_v_layout = QVBoxLayout()  # parameter

        self.layout_init()  # 整体ui
        # self.pic_ori_init()
        # self.pic_res_init()
        # self.para_init()
        # self.btn_init()
        self.click_init()  # 事件
        # self.label_init()  # 显示图片

        self.show()

    def layout_init(self):
        # all > left
        self.left_v_layout.addWidget(self.ori_label)
        self.left_v_layout.addWidget(self.pic_ori_label)
        self.left_v_layout.addSpacing(50)
        self.left_v_layout.addWidget(self.res_label)
        self.left_v_layout.addWidget(self.pic_res_label)
        # all > right
        self.right_v_layout.addLayout(self.para_v_layout)
        self.right_v_layout.addLayout(self.btn_v_layout)

        # all > right > button
        self.btn_v_layout.addWidget(self.file_btn)
        self.btn_v_layout.addWidget(self.run_btn)
        self.btn_v_layout.addSpacing(100)
        self.btn_v_layout.addWidget(self.path_label)
        self.btn_v_layout.addWidget(self.files_btn)
        self.btn_v_layout.addWidget(self.runs_btn)
        self.btn_v_layout.addWidget(self.next_btn)
        # all > right > parameter
        self.para_v_layout.addStretch(1)

        # all
        self.all_h_layout.addLayout(self.left_v_layout)
        self.all_h_layout.addSpacing(100)
        self.all_h_layout.addLayout(self.right_v_layout)
        self.setLayout(self.all_h_layout)

    def click_init(self):
        self.file_btn.clicked.connect(self.openfile)
        self.files_btn.clicked.connect(self.openfiles)
        self.run_btn.clicked.connect(self.run_clicked)  # onClick
        self.runs_btn.clicked.connect(self.runs_clicked)  # onClick
        self.next_btn.clicked.connect(self.next_clicked)
        self.pic_ori_label.myConnectSlot(self.show_child)
        self.pic_res_label.myConnectSlot(self.show_child2)
        # self.run_btn.clicked.connect(QCoreApplication.instance().quit)  # onClick
        self.thread.sinOut.connect(self.run_clicked)  # 手动延迟2s

    def show_image(self, img_path):
        # img = QImage('/home/ubuntu/a.git/mdet/r3det-on-mmdetection/vis1.jpg')
        self.str_path_ori = img_path
        img = QImage(img_path)
        img = self.myResize((self.width // 3), (self.height // 3), img)
        self.pic_ori_label.setPixmap(QPixmap.fromImage(img))
        # self.pic_ori_label.setScaledContents(True)

    def run_clicked(self):
        time.sleep(0.5)
        ori_path = self.str_path_ori
        if ori_path:
            img_path = ori_path.replace("/1/", "/2/")
            self.str_path_res = img_path
            img = QImage(img_path)
            img = self.myResize((self.width // 3), (self.height // 3), img)
            self.pic_res_label.clear()
            self.pic_res_label.setPixmap(QPixmap.fromImage(img))
            # self.pic_res_label.setScaledContents(True)
        # else:
        #     TODO: 弹框提示"请先上传图片"

    def load_txt(self):
        self.pic_res_label.clear()
        self.pic_res_label.setText("(正在检测中,请勿退出...)")
        self.thread.start()

    def runs_clicked(self):
        self.load_txt()

    def next_clicked(self):
        files = self.list_imgs
        if files:
            self.list_imgs_inx = (self.list_imgs_inx + 1) % len(files)
            inx = self.list_imgs_inx
            # print("!!!", inx)
            dir = self.str_dir_ori

            fullname = os.path.join(dir, files[inx])
            # print("####", fullname)
            if fullname:
                self.show_image(fullname)
                self.run_clicked()
            # TODO:
            # TODO:

    def myResize(self, W, H, pil_image):
        w, h = pil_image.width(), pil_image.height()  # 获取图像的原始大小
        if w and h:
            f1 = 1.0 * W / w
            f2 = 1.0 * H / h
            factor = min([f1, f2])
            width = int(w * factor)
            height = int(h * factor)
            # return pil_image.resize(width, height)
            return pil_image.scaled(width, height, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
        return pil_image

    def openfile(self):
        file_name = QFileDialog.getOpenFileName(self, '选择图片', "./",
                                                "Images (*.tiff *.png *.jpg);;All Files (*)")[0]
        if file_name:
            self.show_image(file_name)  # 显示图片
            self.pic_res_label.clear()

            print(type(file_name))
            print(file_name)

    def openfiles(self):
        file_name = QFileDialog.getExistingDirectory(self, '选择文件夹')
        if file_name:
            # self.show_image(file_name)  # 显示图片
            # self.pic_res_label.clear()
            self.path_label.setText(file_name)
            self.get_filelist(file_name)  # list
            img_1 = self.list_imgs[0]
            if img_1:
                fullname = os.path.join(file_name, img_1)
                self.show_image(fullname)
                self.pic_res_label.clear()
            # print(type(file_name))
            # print(file_name)

    @pyqtSlot()
    def on_click(self):
        print('PyQt5 button click')
        self.uplbtn.setText('', )

    def get_filelist(self, dir):
        for home, dirs, files in os.walk(dir):
            self.list_imgs = files
            self.str_dir_ori = home


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

子窗口

class Child(QWidget):  # 子窗口
    def __init__(self):
        super().__init__()
        self.img_label = QLabel(self)
        self.scroll_area = QScrollArea()

        self.img_label.setAlignment(Qt.AlignCenter)
        self.img_label.setBackgroundRole(QPalette.Dark)
        self.img_label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.img_label.setScaledContents(True)

        self.scroll_area.setBackgroundRole(QPalette.Dark)
        self.scroll_area.setWidget(self.img_label)

        self.createBtns()
        self.setMinimumSize(600, 800)

    def showMaximized(self, path):
        if path:
            super().showMaximized()
            self.img_label.setPixmap(QPixmap(path))
            self.scale_factor = 1.0
            self.img_label.adjustSize()

    def createBtns(self):
        self.btn_zoomIn = QPushButton('+ (25%)', self)
        self.btn_zoomIn.clicked.connect(self.zoomIn)
        self.btn_zoomOut = QPushButton('- (25%)', self)
        self.btn_zoomOut.clicked.connect(self.zoomOut)
        self.btn_normalsize = QPushButton('原图', self)
        self.btn_normalsize.clicked.connect(self.normalSize)

        self.btns_h_layout = QHBoxLayout()
        self.btns_h_layout.addWidget(self.btn_zoomIn)
        self.btns_h_layout.addWidget(self.btn_zoomOut)
        self.btns_h_layout.addWidget(self.btn_normalsize)

        self.all_v_layout = QVBoxLayout()
        self.all_v_layout.addLayout(self.btns_h_layout)
        self.all_v_layout.addWidget(self.scroll_area)

        self.setLayout(self.all_v_layout)

    def zoomIn(self):
        if self.scale_factor < 3.0:
            self.scaleImage(1.25)

    def zoomOut(self):
        if self.scale_factor > 0.333:
            self.scaleImage(0.8)

    def normalSize(self):
        self.img_label.adjustSize()
        self.scale_factor = 1.0

    def scaleImage(self, factor):
        self.scale_factor *= factor
        self.img_label.resize(self.scale_factor * self.img_label.pixmap().size())
        self.adjustScrollBar(self.scroll_area.horizontalScrollBar(), factor)
        self.adjustScrollBar(self.scroll_area.verticalScrollBar(), factor)

    def adjustScrollBar(self, scrollBar, factor):
        scrollBar.setValue(int(factor * scrollBar.value()
                               + ((factor - 1) * scrollBar.pageStep() / 2)))

参考博客

1)QThread 进程
2)QMainWindow 图片查看器1图片查看器2
3)PyQt5 入门教程

相关文章

网友评论

      本文标题:PyQt5实现一个检测界面

      本文链接:https://www.haomeiwen.com/subject/kqkdcltx.html