使用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 创造一个软件,的主要内容,如果未能解决你的问题,请参考以下文章