学习pyqt开发软件

Posted 东东就是我

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习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__()

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)

2.小技巧

2.1 使用函数名代替connect链接

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

2.2 选择文件

def check_file(self):

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

2.3 选择文件夹

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

2.4 使用stackedWidget作为页面跳转

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

self.stackedWidget.setCurrentIndex(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()  # 设置列宽高按照内容自适应

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)

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)
#触发信号
    self.QThread.start()
    self.stackedWidget.setCurrentIndex(5)
    self.thread_add_image.send_thread_state.emit(filepath)

完整的例子

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)

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)


在这里插入图片描述

以上是关于学习pyqt开发软件的主要内容,如果未能解决你的问题,请参考以下文章

markdown 学习

学习pyqt开发软件

小白学习pyqt5应该选哪本书比较好?

思源黑体怎么刷了几次刷不上

vnpy源码阅读学习PyQt5的学习

PyQt5学习笔记2-GUI编程基础-2