PyQt5系列教程(4):我猜、我猜、我猜猜猜

上回我們說到了改變主窗口圖標,設置一個小按鈕、並且關閉這個窗口。當然最後我們仍然用Qt設計師實現了這一系列的功能,沒有用到一滴代碼。

今天這期我們將更加完善一下相關的小部件(唯一的按鈕用途有所改變),來完成一個簡單的猜數字遊戲。ok,開始吧!

------------------------------------------------------華麗的分割線----------------------------------------------------------

還記得我們在《Python零基礎入門10天搞定》這門課第四天的內容中介紹了用while循環來實現猜數字的遊戲嗎?如下圖:

今天我們就要用圖形界面來實現這個程序。如下圖:

本次課程涉及的知識點,主要是以下幾點:

  • 按鈕小提示

  • QLineEdit小部件使用

  • QMessageBox的使用

  • 關閉窗口事件觸發

------------------------------------------------------華麗的分割線----------------------------------------------------------

同以往一樣,我們還是根據代碼來逐一講解。

#!/usr/bin/python3nn#coding = utf-8nnimport sysnfrom PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QLineEditnfrom PyQt5.QtGui import QIconnfrom random import randintnnclass Example(QWidget):nn def __init__(self):nn super().__init__()n self.initUI()n self.num = randint(1,100) nn def initUI(self):nn self.setGeometry(300, 300, 300, 220)n self.setWindowTitle(學點編程吧--猜數字)n self.setWindowIcon(QIcon(xdbcb8.ico))nn self.bt1 = QPushButton(我猜, self)n self.bt1.setGeometry(115, 150, 70 ,30)n self.bt1.setToolTip(<b>點擊這裡猜數字</b>)n self.bt1.clicked.connect(self.showMessage) nn self.text = QLineEdit(在這裡輸入數字, self)n self.text.selectAll()n self.text.setFocus()n self.text.setGeometry(80, 50, 150 ,30)nn self.show() nn def showMessage(self):nn guessnumber = int(self.text.text())n print(self.num) n n if guessnumber > self.num:n QMessageBox.about(self, 看結果,猜大了!)n self.text.setFocus() n elif guessnumber < self.num:n QMessageBox.about(self, 看結果,猜小了!)n self.text.setFocus() n else:n QMessageBox.about(self, 看結果,答對了!進入下一輪!)n self.num = randint(1,100)n self.text.clear()n self.text.setFocus() n n def closeEvent(self, event):nn reply = QMessageBox.question(self, 確認, 確認退出嗎, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)n if reply == QMessageBox.Yes:n event.accept() n else:n event.ignore()nnif __name__ == __main__:nn app = QApplication(sys.argv)n ex = Example()n sys.exit(app.exec_())n

上面這個程序實現的主要功能是,系統隨機產生一個1-100之間的整數,我們去猜,看看能否猜中這個數字。

import sysnnfrom PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QLineEditnnfrom PyQt5.QtGui import QIconnnfrom random import randintn

本次程序中我們使用到的模塊,較上次教程多了QMessageBox, QLineEdit類和random模塊。

def __init__(self):nn super().__init__()nn self.initUI()nn self.num = randint(1,100)n

類在進行初始化的時候,自動產生一個1-100的隨機整數。

self.bt1.setToolTip(<b>點擊這裡猜數字</b>)n

要創建一個工具提示,我們調用setTooltip()方法。 我們可以使用富文本格式。滑鼠停留在按鈕上就會出現,如下圖:

self.bt1.clicked.connect(self.showMessage)n

當按鈕被單擊時我們調用showMessage())方法去響應執行。下一章節我們重點介紹PyQt5信號與槽的關係。

self.text = QLineEdit(在這裡輸入數字, self)nnself.text.selectAll()nnself.text.setFocus()nnself.text.setGeometry(80, 50, 150 ,30)n

這裡建立一個QLineEdit對象,用於讓玩家輸入數字。「在這裡輸入數字」是當窗口出現時出現的默認字元;selectAll()方法則是可以理解為將「在這裡輸入數字」進行全選,方便輸入數字,否則你還得手動全選刪除默認字元,如下圖:

setFocus()就是讓焦點置於文本欄中,方便用戶輸入,不然還得手動在文本欄中單擊一下,很是麻煩。沒有焦點的效果如下:

setGeometry()就是設置小部件的擺放坐標以及大小。

def showMessage(self):nn guessnumber = int(self.text.text())nn if guessnumber > self.num:nn QMessageBox.about(self, 看結果,猜大了!)nn self.text.setFocus()nn elif guessnumber < self.num:nn QMessageBox.about(self, 看結果,猜小了!)nn self.text.setFocus()nn else:nn QMessageBox.about(self, 看結果,答對了!進入下一輪!)nn self.num = randint(1,100)nn self.text.clear()nn self.text.setFocus()n

這裡就是對猜測的數字和系統隨機生成的數字就行判斷了。因為QLineEdit輸入的內容是str類型的,所有我們要進行類型轉換。

QMessageBox.about就是彈出一個對話框,告訴你結果是什麼樣的。如下圖:

事實上QMessageBox除了有about外,還有我們程序中用到的QMessageBox.question

QMessageBox.critical

QMessageBox.warning

QMessageBox.information

QMessageBox對話框包含類型只是圖標不同其他無太大差別。

這裡在說明一下,當我們回答正確的時候,調用clear()方法,將文本欄裡面的內容清除,同時重新生成一個隨機數,並將焦點置於文本欄中。

def closeEvent(self, event):nn reply = QMessageBox.question(self, 確認, 確認退出嗎, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)nn if reply == QMessageBox.Yes:nn event.accept() nn else:nn event.ignore()n

如果關閉QWidget,則生成QCloseEvent。 要修改widget的行為,我們需要重新實現closeEvent()事件處理程序。

我們顯示一個帶有兩個按鈕的消息框:Yes和No。第一個字元串出現在標題欄上。 第二個字元串是對話框顯示的消息文本。 第三個參數指定出現在對話框中的按鈕的組合。 最後一個參數是默認按鈕。 它是初始鍵盤焦點的按鈕。 返回值存儲在答覆變數中。

這裡我們根據返回值進行判斷。 如果我們單擊Yes按鈕,我們接受導致關閉窗口小部件並終止應用程序的事件。 否則我們忽略關閉事件。

------------------------------------------------------華麗的分割線----------------------------------------------------------

好了,整個程序就解釋到這裡,我們嘗試結合eric6和Qt設計師來操作一下。我們從增加按鈕的小提示開始,之前的新建主窗口、增加一個小按鈕、修改窗口標題、圖標之前的教程上都有,這裡就不做重複介紹。

我選中按鈕,在右邊的屬性欄修改ToolTip,如下圖:

完成後,我們編譯一下,然後按下F2執行,看看運行的效果,如下圖:

然後我們增加一個Line Edit部件,並雙擊寫下默認顯示的文字,如下圖:

保存,然後編譯運行一下,看看效果。

然後我們來自定義一下單擊按鈕後會產生的響應。在我們創建的UI上單擊右鍵,選擇生成對話框代碼,如下圖:

接著我們新建一個自定義的方法,如下圖:

完成這個後,其實質就是實現了程序具體的功能和界面相分離了。後期程序在修改界面,只要功能不變,都沒有什麼大的影響。注意我們選擇QpushButton中的clicked信號。

雙擊打開我們自動生成的action.py文件,我們可以看到這個文件導入了我們的UI(Ui_Ui_guess_number.py),並繼承了其中的Ui_MainWindow類,如下圖:

此時我們在自動生成"def on_pushButton_clicked(self):"函數中增加我們自定義的按鈕響應函數,完成我們的小遊戲。

def on_pushButton_clicked(self):nn """nn Slot documentation goes here.nn """nn # TODO: not implemented yetnn guessnumber = int(self.lineEdit.text())nn print(self.num)nn if guessnumber > self.num:nn QMessageBox.about(self, 看結果,猜大了!)nn self.lineEdit.setFocus()nn elif guessnumber < self.num:nn QMessageBox.about(self, 看結果,猜小了!)nn self.lineEdit.setFocus()nn else:nn QMessageBox.about(self, 看結果,答對了!進入下一輪!)nn self.num = randint(1,100)nn self.lineEdit.clear()nn self.lineEdit.setFocus()n

當然要想順利執行,還需要增加導入的模塊,最終action.py的代碼如下:

from PyQt5.QtCore import pyqtSlotnnfrom PyQt5.QtWidgets import *nnfrom Ui_Ui_guess_number import Ui_MainWindownnfrom random import randintnnimport sysnnnclass Action(QMainWindow, Ui_MainWindow):nn """n Class documentation goes here.nn """n def __init__(self, parent=None):nn """n Constructornn @param parent reference to the parent widgetnn @type QWidgetnn """nn super(Action, self).__init__(parent)nn self.setupUi(self)nn self.num = randint(1,100)nn self.show()nn def closeEvent(self, event):nn reply = QMessageBox.question(self, 確認, 確認退出嗎, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)nn if reply == QMessageBox.Yes:n event.accept()n else:n event.ignore()n nn @pyqtSlot()nn def on_pushButton_clicked(self):nn """n Slot documentation goes here.n """n # TODO: not implemented yetnn guessnumber = int(self.lineEdit.text())nn print(self.num)nn if guessnumber > self.num:nn QMessageBox.about(self, 看結果,猜大了!)nn self.lineEdit.setFocus()nn elif guessnumber < self.num:nn QMessageBox.about(self, 看結果,猜小了!)nn self.lineEdit.setFocus()nn else:nn QMessageBox.about(self, 看結果,答對了!進入下一輪!)nn self.num = randint(1,100)nn self.lineEdit.clear()nn self.lineEdit.setFocus()nnif __name__ == "__main__":nn app = QApplication(sys.argv)nn action = Action()nn sys.exit(app.exec_())n

------------------------------------------------------華麗的分割線----------------------------------------------------------

最後我們總結一下今天的內容:

  • 按鈕小提示

  • QLineEdit小部件使用

  • QMessageBox的使用

  • 關閉窗口事件觸發

  • 使用Qt設計師完成了小遊戲的製作

ok,今天就到這裡,我們下期再約。

如果你想要本次教程中的相關源碼,請關注微信公眾號:學點編程吧,發送pyqt54,會自動得到相應的百度網盤下載鏈接。

推薦閱讀:

PyQt5番外篇(2-2):沖頂大會語音答題輔助小工具之解析篇——界面搭建
PyQt5系列教程(6):布局
教程 | pyqt5極速打包界面軟體
PyQt5系列教程(15):單選按鈕
PyQt5系列教程(18):微調框1

TAG:PyQt | Python | Python教程 |