前言
Pyqt5 是一套Qt 应用框架与 python的结合,同时支持 2.x 和 3.x。是附属于 python 一款强大的 GUI 库。
本片文章写的 图片浏览程序 就是基于 pyqt5 所完成的,由于 图片预览器 中我们需要增加一些滚动滑轮,所以这里我用到的控件主要是 pyqt5的 QScrollArea ;能够伴随着图片的不断增加而增加页面空间,
可以看一下最终的实现效果:
实现过程
实现这个 图片浏览程序 主要分为两大模块:界面模块 和 逻辑实现模块
界面模块
就是程序的 UI 界面,与用户交互所用到的平台;主界面是用 QWidget 开发的,界面利用垂直布局分布 ( 这里用到的是 QVBoxlayout 控件):主界面上面添加两个起始按钮(QPushbutton),界面的下面放置就是一个 QScrollArea 组件(滚动条);
class img_viewed(QWidget): def __init__(self,parent =None): super(img_viewed,self).__init__(parent) self.parent = parent self.width = 960 self.height = 500 self.scroll_ares_images = QScrollArea(self) self.scroll_ares_images.setWidgetResizable(True) self.scrollAreaWidgetContents = QWidget(self) self.scrollAreaWidgetContents.setObjectName('scrollAreaWidgetContends') # 进行网络布局 self.gridLayout = QGridLayout(self.scrollAreaWidgetContents) self.scroll_ares_images.setWidget(self.scrollAreaWidgetContents) self.scroll_ares_images.setGeometry(20, 50, self.width, self.height) self.vertocal1 = QVBoxLayout() # self.meanbar = QMenu(self) # self.meanbar.addMenu('&菜单') # self.openAct = self.meanbar.addAction('&Open',self.open) # self.startAct =self.meanbar.addAction('&start',self.start_img_viewer) self.open_file_pushbutton =QPushButton(self) self.open_file_pushbutton.setGeometry(150,10,100,30) self.open_file_pushbutton.setObjectName('open_pushbutton') self.open_file_pushbutton.setText('打开文件夹...') self.open_file_pushbutton.clicked.connect(self.open) self.start_file_pushbutton = QPushButton(self) self.start_file_pushbutton.setGeometry(750, 10, 100, 30) self.start_file_pushbutton.setObjectName('start_pushbutton') self.start_file_pushbutton.setText('开始') self.start_file_pushbutton.clicked.connect(self.start_img_viewer) self.vertocal1.addWidget(self.scroll_ares_images) if __name__ =='__main__': app =QApplication(sys.argv) windo = img_viewed() windo.show() sys.exit(app.exec_())
预览效果如下:
上面的 QScrollArea 模块内部又加了一个 QWidget 组件,因为图片分布是逐排顺序进行的,所以组件的内部利用的是网络布局分布( QGridLayout 分布控件 )
逻辑功能实现
逻辑界面已经完成,接下来就是给界面加上相应的功能:
- 文件打开;软件启动功能开发;
- 对图片排布开发相应的功能;
文件打开 这里用到的是 QFileDialog.getExistingDirectory 控件;然后用函数进行封装起来,如果选取的文件为空,需要弹出一个提示对话框来告诉用户,选择的文件夹不合法:
def open(self): file_path = QFileDialog.getExistingDirectory(self, '选择文文件夹', '/') if file_path ==None: QMessageBox.information(self,'提示','文件为空,请重新操作') else: self.initial_path =file_path#self.initial_path用来存放图片所在的文件夹
然后就是在 类的主功能函数 init 下面加上一行代码,让打开按钮对这个函数进行衔接:
self.open_file_pushbutton.clicked.connect(self.open)
然后就能达到下面的效果了:
软件启动 图片文件夹已经获取到了,接下来就是对对文件夹中的图片进行预览功能的开发:
图片布局与显示问题:图片布局就是之前提到的网络布局方式(Qgridlayout),图片显示是利用 (Qlbel控件)
图片布局分布时,首先设定图片的固定宽度,然后根据自己设定窗口大小,进行图片 分布,每排容纳的图片数量 = 设定窗口 / 图片固定宽度;
初始的时候把图片的所在位置都设为0,然后每当每一排的图片数量达到最大容纳数量时,就加一;
def addImage(self, pixmap, image_id): #图像法列数 nr_of_columns = self.get_nr_of_image_columns() #这个布局内的数量 nr_of_widgets = self.gridLayout.count() self.max_columns =nr_of_columns if self.col < self.max_columns: self.col =self.col +1 else: self.col =0 self.row +=1 print('行数为{}'.format(self.row)) print('此时布局内不含有的元素数为{}'.format(nr_of_widgets)) print('列数为{}'.format(self.col)) clickable_image = QClickableImage(self.displayed_image_size, self.displayed_image_size, pixmap, image_id) clickable_image.clicked.connect(self.on_left_clicked) clickable_image.rightClicked.connect(self.on_right_clicked) self.gridLayout.addWidget(clickable_image, self.row, self.col) def loc_fil(self,stre): print('存放地址为{}'.format(stre)) self.initial_path = stre #下面两个函数是用来接受传递信号用的; def geng_path(self,loc): print('路径为,,,,,,{}'.format(loc)) def gen_type(self,type): print('图片类型为:,,,,{}'.format(type))
图片显示的话,利用的 Qpixmap 控件;这里又开发了一个类,用来传递经过处理(尺寸改变,加图片源地址) 之后的 Pixmap,用的是 pyqSignal 方法(信号传递)
QClickableImage ;这个模块主要是生成一个 QWidget : 这个 Qwidget用的是垂直布局分布,上面放的是图片,下面放的是图片的 地址 ( image_id );
class QClickableImage(QWidget): image_id ='' def __init__(self,width =0,height =0,pixmap =None,image_id = ''): QWidget.__init__(self) self.layout =QVBoxLayout(self) self.label1 = QLabel() self.label1.setObjectName('label1') self.lable2 =QLabel() self.lable2.setObjectName('label2') self.width =width self.height = height self.pixmap =pixmap if self.width and self.height: self.resize(self.width,self.height) if self.pixmap: pixmap = self.pixmap.scaled(QSize(self.width,self.height),Qt.KeepAspectRatio,Qt.SmoothTransformation) self.label1.setPixmap(pixmap) self.label1.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.label1) if image_id: self.image_id =image_id self.lable2.setText(image_id) self.lable2.setAlignment(Qt.AlignCenter) ###让文字自适应大小 self.lable2.adjustSize() self.layout.addWidget(self.lable2) self.setLayout(self.layout) clicked = pyqtSignal(object) rightClicked = pyqtSignal(object) def mouseressevent(self,ev): print('55555555555555555') if ev.button() == Qt.RightButton: print('dasdasd') #鼠标右击 self.rightClicked.emit(self.image_id) else: self.clicked.emit(self.image_id) def imageId(self): return self.image_id
当以上所有功能都已经开发完之后,接下来就是对那个 软件启动 按钮添加功能:这里做的是一个函数封装,主要实现是先递归文件夹中的每张照片,然后对每张照片利用 addImage() 函数添加到界面的相应位置。
def start_img_viewer(self): if self.initial_path: file_path = self.initial_path print('file_path为{}'.format(file_path)) print(file_path) img_type = 'png' if file_path and img_type: png_list = list(i for i in os.listdir(file_path) if str(i).endswith('.{}'.format(img_type))) print(png_list) num = len(png_list) if num !=0: for i in range(num): image_id = str(file_path + '/' + png_list[i]) print(image_id) pixmap = QPixmap(image_id) self.addImage(pixmap, image_id) print(pixmap) QApplication.processEvents() else: QMessageBox.warning(self,'错误','生成图片文件为空') self.event(exit()) else: QMessageBox.warning(self,'错误','文件为空,请稍后') else: QMessageBox.warning(self, '错误', '文件为空,请稍后')
最后设置一个程序的启动主函数 –name-- ==–main– ;
if __name__ =='__main__': app =QApplication(sys.argv) windo = img_viewed() windo.show() sys.exit(app.exec_())
最后
以上就是基于 pyqt5 开发这个简单 图片编辑器的 整个过程;程序中存在的不足当然还有很多,界面也没有进行任何的美化,因为自己也刚接触这个库,也在学习阶段当中;