界面设计
根据功能,将主窗口分为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)))
网友评论