• 使用pyqt 创造一个软件,


    1.一个软件架构的注意:

    1.任何表格或者表单需要一个主键!!!!!!(方便后期的查重和查找)
    2.通过qt designer 生成ui,然后通过pyuic生成的py文件,一定不要改!!!!再创建一个logic类继承UI类。我们只修改logic(后面修改UI 也不影响我们的logic模块)

    from UI.newdata import Ui_NewData
    class NewData(QtWidgets.QWidget, Ui_NewData):
        def __init__(self):
            super(NewData, self).__init__()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.一定要把可以复用的代码封装好,一个pyqt项目,其中有很多代码可以复用,不提取的话,会造成代码冗余。
    4.一定要有log模块和配置文件模块,方便后期的维护和修改。很多控件可以根据配置文件展示不同的内容
    5.耗时的io操作一定要做线程处理

    io
    class ThreadAddImage(QObject):
        send_thread_state = pyqtSignal(str)  # 信号
        def __init__(self, lable, item):
            super(ThreadAddImage, self).__init__()
            self.show_label = lable
            self.item = item
            self.item.setIconSize(QSize(150, 100))
        def get_image_paths(self, img_dir):
    
    主函数
    self.QThread = QThread()
    self.thread_add_image = ThreadAddImage(
    self.label_show, self.listWidget_image)
    self.thread_add_image.moveToThread(self.QThread)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.小技巧

    2.1 使用函数名代替connect链接

    @pyqtSlot()
        def on_按钮名称_clicked(self):
    
    • 1
    • 2

    2.2 选择文件

    def check_file(self):
    
        fname, _ = QtWidgets.QFileDialog.getOpenFileName(
            self, "打开文件", "./",)  # 如果添加一个内容则需要加两个分号
        if fname != "":  # 判断路径非空
            self.lineEdit_modelpath.setText(fname.split("/")[-1])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3 选择文件夹

    def check_file(self):
        m = QtWidgets.QFileDialog.getExistingDirectory(None, "选取文件夹", "C:/")
        self.lineEdit_path.setText(m)
    
    • 1
    • 2
    • 3

    2.4 使用stackedWidget作为页面跳转

    设置对应的index,跳转到相应页面

    self.stackedWidget.setCurrentIndex(1)
    
    • 1

    2.5 使用tablewidget作为数据展示

    2.5.1 tablewidget 添加数据

    最后一列可以添加button,更好的用户交互

    def add_table_widget(tem_tablew_idget, project_list, button_widget, is_exits):
        """
        增加talbe数据
        :param is_exits:
        :param tem_tablew_idget:
        :param project_list:
        :param button_widget:
        """
        row_cnt = tem_tablew_idget.rowCount()  # 返回当前行数(尾部)
        tem_tablew_idget.insertRow(row_cnt)  # 尾部插入一行新行表格
        column_cnt = tem_tablew_idget.columnCount()  # 返回当前列数
        for column in range(column_cnt - 1):
            tem_tablew_idget.setItem(
                row_cnt, column, QTableWidgetItem(
                    project_list[column]))  # 最后,将(行,列,内容)配置
            if is_exits:
                tem_tablew_idget.item(
                    row_cnt, column).setBackground(
                    QtGui.QColor(
                        0, 255, 0))
            else:
                tem_tablew_idget.item(
                    row_cnt, column).setBackground(
                    QtGui.QColor(
                        255, 0, 0))
        tem_tablew_idget.setCellWidget(row_cnt, column_cnt - 1, button_widget)
        tem_tablew_idget.resizeColumnsToContents()  # 设置列宽高按照内容自适应
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2.5.1 tablewidget 删除数据(给对应的button绑定函数)

        def delete_button(self, tem_table_widget, filepath, ):
            """
            新建工程 item  删除按钮函数
            """
            button = self.sender()
            if button:
                # 确定位置的时候这里是关键
                row = tem_table_widget.indexAt(button.parent().pos()).row()
                tem_table_widget.removeRow(row)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.6 线程 使用moveToThread

    其中 函数如果需要传递参数,使用信号槽,比如多线程执行 self.thread_add_image.get_image_paths
    可以通过触发信号send_thread_state,

    self.QThread = QThread()
    self.thread_add_image = ThreadAddImage(
        self.label_show, self.listWidget_image)
    self.thread_add_image.moveToThread(self.QThread)
    self.thread_add_image.send_thread_state.connect(
            self.thread_add_image.get_image_paths)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    #触发信号
        self.QThread.start()
        self.stackedWidget.setCurrentIndex(5)
        self.thread_add_image.send_thread_state.emit(filepath)
    
    • 1
    • 2
    • 3
    • 4

    完整的例子

    class ThreadAddImage(QObject):
        send_thread_state = pyqtSignal(str)  # 信号
        def __init__(self, lable, item):
            super(ThreadAddImage, self).__init__()
        def get_image_paths(self, img_dir):
            handle = int(self.thread().currentThreadId())
            print("Run1 thread {}".format(handle))
    
    class MainWindow(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            self.setupUi(self)
            # 创建一个线程
            self.QThread = QThread()
            self.thread_add_image = ThreadAddImage(
                self.label_show, self.listWidget_image)
            self.thread_add_image.moveToThread(self.QThread)
    
            # 信号绑定槽函数
            self.thread_add_image.send_thread_state.connect(
                self.thread_add_image.get_image_paths)
            handle = int(self.thread().currentThreadId())
            print("Run2 thread {}".format(handle))
        def image_show(self, tem_table_widget, filepath):
            button = self.sender()
            if button:
                # 确定位置的时候这里是关键
                row = tem_table_widget.indexAt(button.parent().pos()).row()
                #激活线程
                self.QThread.start()
       
                self.stackedWidget.setCurrentIndex(5)
                #触发信号绑定的函数
                self.thread_add_image.send_thread_state.emit(filepath)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.7 图像缩略图可以使用listWidget

    2.7.1上面的线程就是使用listWidget,这个有个鼠标滑轮绑定事件,这样可以一次加载一部分图片

    2.7.2点击图片放大绑定事件

    class ThreadAddImage(QObject):
        send_thread_state = pyqtSignal(str)  # 信号
    
        def __init__(self, lable, item):
            super(ThreadAddImage, self).__init__()
            self.show_label = lable
            self.item = item
            self.item.setIconSize(QSize(150, 100))
            # 信号与连接
            self.item.itemSelectionChanged.connect(self.loadImage)
            self.item.verticalScrollBar().valueChanged.connect(self.valueChanged)
    
        def valueChanged(self, value):
            if value == self.item.verticalScrollBar().maximum():
                self.add_image_items(5)
    
        def get_image_paths(self, img_dir):
            self.img_paths = []
            self.image_num = 0
            filenames = os.listdir(img_dir)
    
            for file in filenames:
                if file[-4:] == ".png" or file[-4:] == ".jpg" or file[-4:] == ".bmp":
                    self.img_paths.append(os.path.join(img_dir, file))
            self.add_image_items(15)
    
        def add_image_items(self, num):
            # 图像路径
            for img_path in self.img_paths[self.image_num:self.image_num + num]:
                if os.path.isfile(img_path):
                    img_name = os.path.basename(img_path)
                    item = QListWidgetItem(QIcon(img_path), img_name)
                    self.item.addItem(item)
            self.image_num += num
            handle = int(self.thread().currentThreadId())
            my_logger.info("加载图片")
            print("Run1 thread {}".format(handle))
    
       # 放大图片
        def loadImage(self):
            self.currentImgIdx = self.item.currentIndex().row()
            if self.currentImgIdx in range(len(self.img_paths)):
                self.currentImg = QPixmap(
                    self.img_paths[self.currentImgIdx]).scaledToHeight(600)
                self.show_label.setPixmap(self.currentImg)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    1. 前缀码判定
    node.js - 上传文件至阿里云oss
    引入短信服务
    中国传统节日春节网页HTML代码 春节大学生网页设计制作成品下载 学生网页课程设计期末作业下载 DW春节节日网页作业代码下载
    伽蓝集团进击IPO:原料端价值是国货美妆的新“解药”?
    CTF-misc练习(https://buuoj.cn)之第二页
    浅学Nginx学习笔记
    linux安装常见的中间件和数据库
    elementUI中form表单校验异常,开始就处罚了
    深度学习——(7)分类任务
  • 原文地址:https://blog.csdn.net/qq_33228039/article/details/125432577