前言
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 開發這個簡單 圖片編輯器的 整個過程;程序中存在的不足當然還有很多,界面也沒有進行任何的美化,因爲自己也剛接觸這個庫,也在學習階段當中;整個程序的源碼我已經放在 Github上了 ,地址:Github;