PyQt5系列教程(24):抽象按鈕(QAbstractButton)

抽象按鈕,這個是什麼鬼?

導讀:上期我們介紹了PyQt中的工具按鈕(QToolButton),這期我們介紹些什麼呢?還是按鈕,呵呵。

我們在PyQt5系列教程的第14、15、22、23期中分別介紹了:QCheckBox、QRadioButton、QPushButton、QToolButton,話說這些按鈕都有一個什麼特點呢?它們均繼承了QAbstractButton類

Abstract翻譯成中文就是抽象的意思,QAbstractButton也就是說這是一個高度抽象的按鈕類,以它為基礎,所有的按鈕都具備其父類的方法和屬性,當然還有自己的特點。這也就是為什麼明明在文檔中某個方法沒有出現啊,但是我就是能用,因為來自它的父類QAbstractButton啊。

總體介紹

QAbstractButton類是按鈕小部件的抽象基類,提供了按鈕常見的功能。

這個類實現一個抽象按鈕。該類的子類處理用戶操作,並指定如何繪製按鈕。

QAbstractButton支持普通按鈕和開關按鈕(按下去不會彈起來的那種按鈕)。按鈕可否被選中這個特點在QRadioButton和QCheckBox類中實現的。普通按鈕的特性在QPushButton和QToolButton類中實現;如果有必要它們都提供了開關按鈕的功能。

任何按鈕都可以顯示包含文本和圖標的標籤。setText()設置文本;setIcon()設置圖標。如果一個按鈕被禁用,它的標籤會被改變以使按鈕出現「禁用」的外觀。

如果按鈕是一個文本按鈕,帶有一個包含』&』的字元串,則QAbstractButton會自動創建一個快捷鍵。例如:

button = QPushButton(Ro&ck, self)n

Alt+C快捷鍵被分配給按鈕,即當用戶按Alt+C時,按鈕將調用animateClick()。要顯示一個實際的「&」,請使用「&&」。

您還可以使用setShortcut()函數設置自定義快捷鍵。這對於沒有任何文本的按鈕來說是有用的,因此不能有任何自動的快捷方式。

button.setIcon(QIcon("print.png"))nbutton.setShortcut("Alt+F7")n

QPushButton, QToolButton, QCheckBox, QRadioButton提供的所有按鈕都可以顯示文本和圖標。

一個按鈕可以在對話框中通過QPushButton.setDefault()和QPushButton.setAutoDefault()設置默認按鈕。

QAbstractButton提供了大多數用於按鈕的狀態:

  • isDown()指示按鈕是否被按下。
  • isChecked()指示按鈕是否被選中。只有可被選中的按鈕才能查看其選中的狀態。
  • isEnabled()指示按鈕是否可以被用戶按下。

注意:與其他小部件相反,從QAbstractButton派生的按鈕在禁用時接受滑鼠和上下文菜單事件。

setAutoRepeat()設置如果用戶按住按鈕,按鈕是否自動重複。autoRepeatDelay和autoRepeatInterval定義如何自動重複。

setCheckable()設置按鈕是否為開關按鈕。

isDown()和ischeck()的區別如下:

當用戶單擊一個開關按鈕來選中時,按鈕首先被按下,然後釋放到被選中的狀態。當用戶再次單擊它(要取消選中)時,按鈕首先移動到按下的狀態,然後到未選中的狀態(ischeck()和isDown()都是Flase)。

QAbstractButton提供四種信號:

  1. pressed():當滑鼠游標在按鈕內時,滑鼠左鍵被按下。
  2. release():當在釋放滑鼠左鍵時發出的。
  3. clicked() :當按鈕第一次被按下,然後被釋放;當快捷鍵被鍵入時;click()或者animateClick()被調用時。
  4. toggle():當開關按鈕狀態發生變化時發出的。

為了子類化QAbstractButton,您必須重新實現至少paintEvent()來繪製按鈕的輪廓及其文本或像素圖。通常建議重新實現sizeHint(),有時還可以使用hitButton()(來確定按鈕是否在按鈕中)。對於具有兩個以上狀態的按鈕(如三態按鈕),您還必須重新實現checkStateSet()和nextCheckState()。

更多的介紹,請見官方文檔:QAbstractButton Class

小例子

我們用三個小例子來舉例一下。

第一個小例子部分核心代碼

class Example(QWidget):nn def initUI(self):nn self.resize(500,300)n self.setWindowTitle(關注微信公眾號:學點編程吧--抽象按鈕的學習1(QAbstractButton))nn label1 = QLabel(密碼輸入區,self)n label2 = QLabel(正確密碼:麻,self)n label3 = QLabel(你輸入的密碼:,self)nn self.label4 = QLabel( ,self)nn bt1 = QPushButton(,self)n bt2 = QPushButton(,self)n bt3 = QPushButton(,self)n bt4 = QPushButton(,self)nn bt1.setCheckable(True)n bt2.setCheckable(True)n bt3.setCheckable(True)n bt4.setCheckable(True)nn bt1.setAutoExclusive(True)n bt2.setAutoExclusive(True)n bt3.setAutoExclusive(True)n bt4.setAutoExclusive(True)nn bt1.clicked.connect(self.setPassword)n bt2.clicked.connect(self.setPassword)n bt3.clicked.connect(self.setPassword)n bt4.clicked.connect(self.setPassword)nn def setPassword(self):n word = self.sender().text()n self.label4.setText(word)n if word == :n QMessageBox.information(self,提示,恭喜,密碼正確,可以進入!)n

這個例子當中我們構建了4個開關按鈕,也就是傳說中的那種按下後不彈起來的按鈕。這4個按鈕是互斥的,即每次只能按下1個。只有按對正確的按鈕才會提示密碼正確。下面我們來解析一下。

bt1.setCheckable(True)nbt2.setCheckable(True)nbt3.setCheckable(True)nbt4.setCheckable(True)n

此屬性保存按鈕是否可被選中。默認情況下,該按鈕是不可被選中的。即默認情況下按鈕按下後是要彈起來的,設置後,就像點燈開關一樣,要麼開要麼關,所以叫開關按鈕(這是我自己起的名字)。

bt1.setAutoExclusive(True)nbt2.setAutoExclusive(True)nbt3.setAutoExclusive(True)nbt4.setAutoExclusive(True)n

此屬性保存是否啟用排它性。

如果啟用了自動排它性,那麼屬於同一個父部件的可選中按鈕就會表現得好像它們是相同按鈕組一部分一樣。在這個唯一按鈕組中,任何時候只有一個按鈕可以被選中;選中另一個按鈕會自動取消之前選中過的按鈕。此屬性對屬於其它按鈕組的按鈕沒有影響。

除了單選按鈕之外,autoExclusive是默認關閉的。

def setPassword(self):n word = self.sender().text()n self.label4.setText(word)n if word == :n QMessageBox.information(self,提示,恭喜,密碼正確,可以進入!)n

獲得我們點擊的按鈕上的名稱並與密碼比對,若一致就提示成功!

第二個小例子部分核心代碼

class Example(QWidget):nn def initUI(self):nn self.resize(500,300)n self.setWindowTitle(關注微信公眾號:學點編程吧--抽象按鈕的學習2(QAbstractButton))nn label1 = QLabel(密碼輸入區,self)nn label2 = QLabel(正確密碼:芝麻開門,self)nn label3 = QLabel(你輸入的密碼:,self)nn self.label4 = QLabel( ,self)nn self.bt1 = QPushButton(,self)n self.bt2 = QPushButton(,self)n self.bt3 = QPushButton(,self)n self.bt4 = QPushButton(,self)nn self.bt1.setCheckable(True)n self.bt2.setCheckable(True)n self.bt3.setCheckable(True)n self.bt4.setCheckable(True)nn self.password = nn self.bt1.clicked.connect(self.setPassword)n self.bt2.clicked.connect(self.setPassword)n self.bt3.clicked.connect(self.setPassword)n self.bt4.clicked.connect(self.setPassword)n def setPassword(self,pressed):n word = self.sender().text()n if pressed:n if len(self.password) < 4:n self.password += wordn else:n self.password = self.password.replace(word,)nn self.label4.setText(self.password) n if len(self.password) == 4 and self.password == 芝麻開門:n QMessageBox.information(self,提示,恭喜,密碼正確,可以進入!)n

這個例子和上面那個例子相比,增加了密碼的位數,同時按鈕不再是互斥的了,每次按下按鈕顯示對應的文字,取消按鈕這取消顯示對應的文字,直到密碼正確位置。下面我們來解析一下,例1中涉及到的知識點這裡就不再重複,節約大家時間。

self.password = n

這裡我們新建一個公共變數,用於臨時保存輸入的密碼。

def setPassword(self,pressed):n word = self.sender().text()n if pressed:n if len(self.password) < 4:n self.password += wordn else:n self.password = self.password.replace(word,)nn self.label4.setText(self.password)n if len(self.password) == 4 and self.password == 芝麻開門:n QMessageBox.information(self,提示,恭喜,密碼正確,可以進入!)n

在這個函數中我們要對按鈕的狀態進行判斷,如果我們按下了按鈕就記錄此時的按鈕名稱,如果彈起按鈕則清除之前記錄的按鈕名稱。這個是大致的實現思路。

word = self.sender().text()n

用word記錄我們的點擊的按鈕名稱。

if pressed:n if len(self.password) < 4:n self.password += wordn else:n self.password = self.password.replace(word,)n

只要我們密碼的長度不超過4,每點擊一次都讓self.password更新一次。如果我們取消按鈕的選中狀態,那麼使用replace函數將之前增加的按鈕文字替換空字元。

self.label4.setText(self.password)nif len(self.password) == 4 and self.password == 芝麻開門:n QMessageBox.information(self,提示,恭喜,密碼正確,可以進入!)n

更新我們輸入密碼的內容,並進行密碼匹配。匹配上就彈成功。

第三個小例子部分核心代碼

class Example(QWidget):nn def initUI(self):nn self.resize(500,300)n self.setWindowTitle(關注微信公眾號:學點編程吧--抽象按鈕的學習3(QAbstractButton))nn label1 = QLabel(密碼輸入區,self)nn label2 = QLabel(正確密碼:321,self)nn label3 = QLabel(你輸入的密碼:,self)nn self.label4 = QLabel( ,self)nn self.bt11 = QPushButton(1,self)n self.bt12 = QPushButton(2,self)n self.bt13 = QPushButton(3,self)n self.bt21 = QPushButton(1,self)n self.bt22 = QPushButton(2,self)n self.bt23 = QPushButton(3,self)n self.bt31 = QPushButton(1,self)n self.bt32 = QPushButton(2,self)n self.bt33 = QPushButton(3,self)nn self.btg1 = QButtonGroup(self)n self.btg2 = QButtonGroup(self)n self.btg3 = QButtonGroup(self)nn self.btg1.addButton(self.bt11,1)n self.btg1.addButton(self.bt12,2)n self.btg1.addButton(self.bt13,3)n self.btg2.addButton(self.bt21,1)n self.btg2.addButton(self.bt22,2)n self.btg2.addButton(self.bt23,3)n self.btg3.addButton(self.bt31,1)n self.btg3.addButton(self.bt32,2)n self.btg3.addButton(self.bt33,3)nn self.bt11.setCheckable(True)n self.bt12.setCheckable(True)n self.bt13.setCheckable(True)n self.bt21.setCheckable(True)n self.bt22.setCheckable(True)n self.bt23.setCheckable(True)n self.bt31.setCheckable(True)n self.bt32.setCheckable(True)n self.bt33.setCheckable(True)nn self.pwd1,self.pwd2,self.pwd3 = ,,nn self.btg1.buttonClicked.connect(self.setPassword)n self.btg2.buttonClicked.connect(self.setPassword)n self.btg3.buttonClicked.connect(self.setPassword)n def setPassword(self,pressed):n sender = self.sender()n if sender == self.btg1:n self.pwd1 = str(self.btg1.checkedId())n elif sender == self.btg2:n self.pwd2 = str(self.btg2.checkedId())n elif sender == self.btg3:n self.pwd3 = str(self.btg3.checkedId())nn self.label4.setText(self.pwd1 + self.pwd2 + self.pwd3)n if self.pwd1 + self.pwd2 + self.pwd3 == 321:n QMessageBox.information(self,提示,恭喜,密碼正確,可以進入!)n

這個例子我們設立了9個按鈕,分成了3組,每組中的按鈕是互斥的,同樣還是輸入密碼並匹配。下面我們來解析一下,例1、2中涉及到的知識點這裡就不再重複,節約大家時間。

self.btg1 = QButtonGroup(self)nself.btg2 = QButtonGroup(self)nself.btg3 = QButtonGroup(self)nnself.btg1.addButton(self.bt11,1)nself.btg1.addButton(self.bt12,2)nself.btg1.addButton(self.bt13,3)nself.btg2.addButton(self.bt21,1)nself.btg2.addButton(self.bt22,2)nself.btg2.addButton(self.bt23,3)nself.btg3.addButton(self.bt31,1)nself.btg3.addButton(self.bt32,2)nself.btg3.addButton(self.bt33,3)n

我們新建3個按鈕組,並將按鈕加入到對應的按鈕組中,同時設立它們的id號。

self.pwd1,self.pwd2,self.pwd3 = ,,n

新建3個變數存儲我們輸入的3個密碼。

self.btg1.buttonClicked.connect(self.setPassword)nself.btg2.buttonClicked.connect(self.setPassword)nself.btg3.buttonClicked.connect(self.setPassword)n

當我們點擊按鈕組中的按鈕的時候會調用setPassword函數。

def setPassword(self,pressed):n sender = self.sender()n if sender == self.btg1:n self.pwd1 = str(self.btg1.checkedId())n elif sender == self.btg2:n self.pwd2 = str(self.btg2.checkedId())n elif sender == self.btg3:n self.pwd3 = str(self.btg3.checkedId())nn self.label4.setText(self.pwd1 + self.pwd2 + self.pwd3)n if self.pwd1 + self.pwd2 + self.pwd3 == 321:n QMessageBox.information(self,提示,恭喜,密碼正確,可以進入!)n

這個函數很好理解。就是說當我們點擊不同組別的按鈕的時候,都會記錄下它的id號(這是個int數字),然後保存在我們的臨時變數中。

label4中的文字自然會隨著我們點擊按鈕的不同發生變化;

同時如果我們輸入的密碼和正確密碼是一致的,那麼就會彈出消息對話框了。

最後

ok,今天的介紹暫時就到這裡吧,下期我們再見。如果你喜歡本篇文章,請給我點贊、讚賞(推薦, 哈哈),分享給你的好友們吧!

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

同時請動動小手在微信公眾號號中間的菜單,完成我們的滿意度調查問卷,提升我們的服務質量,謝謝!


推薦閱讀:

TAG:PyQt | Python | Python教程 |