一個簡單的例子
以下是一個用pyqt5寫成的簡單圖片顯示程式。
該圖片顯示程式由一個QLabel和QPushButton組成,當單擊按鈕時,會彈出一個檔案選擇對話方塊,讓使用者選擇合適的圖片檔案。在使用者按下確定後程式會將使用者所選擇的圖片進行顯示。
啟動指令碼
main.py依然作為這個程式的啟動指令碼。
import sysfrom PyQt5.QtWidgets import QApplicationfrom dumbDialog import DumbDialog
以上代碼匯入必要的pyqt5類,完成指令碼的啟動。其中,我們對上一節例子中的DumbDialog進行了一些小小的修改。不再將它寫在main.py裡,而是單獨寫在一個名為dumbdialog.py的指令檔裡,之後再通過上述代碼對該類進行匯入。接下來的代碼:
if __name__ == "__main__": app = QApplication(sys.argv) #建立QApplication類的執行個體 dia = DumbDialog() #建立DumbDialog類的執行個體 dia.show() #顯示程式主視窗 app.exec_() #開啟事件主迴圈
如果是曾經學過Qt的同學,會不會覺得以上的代碼看著非常的熟悉。沒錯,pyqt和c++的Qt除了細節上有一點不同之外,其它的套路都是差不多的。大部分類的屬性和方法都沒有作任何的改變。除了幾個關鍵的地方之外,其它部分完全是可以參考Qt的c++文檔完成的。 程式的主視窗
dumbDialog.py中的DumbDialog類作為程式的主視窗,由一個QLabel負責顯示資訊和圖片以及一個QPushButton負責彈出檔案對話方塊,並在使用者選擇合適圖片後通過QLabel進行顯示。
首先是類的定義:
class DumbDialog(QDialog):
括弧中的QDialog類表示這個類是繼承於QDialog的,這個是python物件導向的一個基礎知識,不懂的同學可以去查閱相關的資料,個人認為這個還是比較簡單的,這裡就不再贅述。
然後是這個類的建構函式:
def __init__(self, parent = None): super(DumbDialog, self).__init__(parent) self._title = "image_loader" #設定類執行個體成員_title,它的值為字串的"image_laoder" self._diawidth = 300 #設定執行個體成員_diawidth,它的值為300 self._diaheight = 450 self.setWindowTitle(self._title) #設定視窗標題 self.setMinimumHeight(self._diaheight) #設定視窗最小的大小 self.setMinimumWidth(self._diawidth) self.imageView = QLabel("add a image file") #得到一個QLabel的執行個體,並將它儲存在成員imageView裡,負責顯示訊息以及圖片 self.imageView.setAlignment(Qt.AlignCenter) #設定QLabel置中顯示 self.btn_open = QPushButton("open") #執行個體化一個名為"open"的按鈕,並將它儲存在類成員btn_open中,負責去得到圖片的路徑,並在QLabel中顯示 self.btn_open.clicked.connect(self.on_btn_open_clicked) #pyqt5中訊號與槽的串連 self.vlayout = QVBoxLayout() self.vlayout.addWidget(self.imageView) self.vlayout.addWidget(self.btn_open) self.setLayout(self.vlayout)
我們可以看到建構函式中,與訊號和槽串連相關的代碼為:
self.widget_name.signal_name.connect(self.slot_name)
而以上的代碼在pyqt4中是通過以下的方式進行表示的:
self.connect(self.widget_name, SIGNAL("signal_name(args)"), self.slot_name)
如果同學們以前學過c++版本的Qt,可以很容易的發現,在pyqt4中的訊號與槽的串連與在c++中訊號與槽的串連最為相似,但是比起pyqt5中的新方法這種方法就略顯麻煩,冗雜了。 槽函數
在pyqt5中,槽函數數一般是通過python裝飾器@pyqtSlot(typename)進行修飾的。譬如,例子中槽函數表示為:
@pyqtSlot(bool)def on_btn_open_clicked(self, checked): self.filename = QFileDialog.getOpenFileName(self, "OpenFile", ".", "Image Files(*.jpg *.jpeg *.png)")[0] if len(self.filename): self.image = QImage(self.filename) self.imageView.setPixmap(QPixmap.fromImage(self.image)) self.resize(self.image.width(), self.image.height())
通過查閱Qt文檔我們可以知道,clicked這個訊號是帶一個bool的參數的,因此我們需要在裝飾器pyqtSlot裡進行聲明,即bool。之後,上述槽函數的第二個參數”checked”,即為這個bool參數的具體值。對於python裝飾器還不是很理解的同學可以去查閱相關資料,這個個人認為還是比較麻煩不好懂的。同學們可以多花費一點時間在這個上面。
這個槽函數要做的工作非常簡單,在使用者按下按鈕後先彈出一個檔案對話方塊,使用者選擇圖片檔案後就把檔案名稱儲存在self.filename裡。之後通過這個具體的檔案路徑建立一個QImage的執行個體目的是為了為使用QPixmap.fromImage方法做準備。之後通過這個靜態方法產生一個QPixmap的執行個體,之後就可以通過QLabel的setPixmap設定圖片了。整個過程還是非常簡單易懂的。如果對上述的過程還有疑問,可以查閱Qt的相關文檔。 總結
至此,這個簡單的例子就分析完畢了。同學們可以在https://git.oschina.net/linuxlike/PyQtJianYiRuMenZhiNan上下載項目的原始碼進行分析學習。
(本篇文章是我個人分析總結的結果,難免存在不足和錯誤的地方,如果大家看到,還請就相關的問題提出意見,進行交流。)