pyqt5 实现右键自定义_《快速掌握PyQt5》第十七章 事件处理
事件就是由窗口、控件本身或者PyQt5自身產生的,配合用戶動作的各種響應。“事件”和“信號”非常相似,但請不要歸為一類。
事件類型種類繁多,這里主要介紹一些常用的:窗口關閉事件處理、鼠標事件處理以及鍵盤事件處理。
17.1 窗口關閉事件
當筆者在博客編輯器中進行寫作時,若沒有點擊保存直接關閉窗口時(觸發窗口關閉事件),會出現彈框詢問是否確定離開:
我們來用PyQt5實現類似功能,代碼如下:
import sys from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit, QPushButton, QMessageBox, QVBoxLayoutclass Demo(QWidget):def __init__(self):super(Demo, self).__init__()self.is_saved = True # 1self.textedit = QTextEdit(self) # 2self.textedit.textChanged.connect(self.on_textchanged_func)self.button = QPushButton('Save', self) # 3self.button.clicked.connect(self.on_clicked_func)self.v_layout = QVBoxLayout() self.v_layout.addWidget(self.textedit)self.v_layout.addWidget(self.button)self.setLayout(self.v_layout)def on_textchanged_func(self): if self.textedit.toPlainText(): self.is_saved = Falseelse:self.is_saved = Truedef on_clicked_func(self):self.save_func(self.textedit.toPlainText())self.is_saved = Truedef save_func(self, text): with open('saved.txt', 'w') as f:f.write(text)def closeEvent(self, QCloseEvent): # 4if not self.is_saved:choice = QMessageBox.question(self, '', 'Do you want to save the text?',QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)if choice == QMessageBox.Yes:self.save_func(self.textedit.toPlainText())QCloseEvent.accept()elif choice == QMessageBox.No:QCloseEvent.accept()else:QCloseEvent.ignore()if __name__ == '__main__':app = QApplication(sys.argv)demo = Demo()demo.show()sys.exit(app.exec_())1. is_saved變量用于記錄用戶是否已經進行保存;
2. 實例化一個QTextEdit控件用于文本編輯,將其textChanged信號和自定義的槽函數連接起來:
def on_textchanged_func(self): if self.textedit.toPlainText(): self.is_saved = Falseelse:self.is_saved = True在槽函數中我們判斷在每次文本內容發生變化時,textedit中是否還有文本,若有的話則將is_saved變量設為False,即未保存;若無文本,則將其設為True(如果沒有文本的話,那可以直接關閉窗口,程序不會詢問是否需要保存,因為沒必要)。
3. 實例化一個按鈕用于保存操作,將clicked信號與自定義的槽函數進行連接:
def on_clicked_func(self):self.save_func(self.textedit.toPlainText())self.is_saved = True每次點擊該按鈕就進行保存,不管文本編輯框中是否有文本,文本保存通過save_fcun()函數完成:
def save_func(self, text): with open('saved.txt', 'w') as f:f.write(text)我們將內容保存在當前目錄下的saved.txt函數中。PyQt5提供一個QFileDialog類可以讓我們更好的完成保存操作,后續章節會涉及,這里只是先簡單的完成下保存功能。
4. 這里我們重新定義了QWidget的窗口關閉函數closeEvent(),如果用戶還沒有進行保存,則彈出一個QMessageBox窗口詢問是否保存,若用戶點擊Yes,則調用save_func()函數進行保存,然后通過accept()方法來接收關閉窗口操作,窗口隨之關閉;若點擊No,則不進行保存,但同樣得關閉窗口;若點擊cancel,也不進行保存,并通過ignore()方法來忽略這次關閉窗口的操作。
運行截圖如下,輸入la vie est belle后不點擊Save按鈕,直接關閉窗口,則會出現彈窗詢問是否需要保存:
我們點擊Yes后,則窗口關閉,在項目路徑下出現一個‘saved.txt’文件,里面的文本正是我們之前所輸入的la vie est belle:
17.2 鼠標事件
鼠標移動、按下或者釋放動作都會喚起相應的鼠標事件:
import sys from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayoutclass Demo(QWidget):def __init__(self):super(Demo, self).__init__()self.button_label = QLabel('No Button Pressed', self) # 1self.xy_label = QLabel('x:0, y:0', self) # 2self.global_xy_label = QLabel('global x:0, global y:0', self) # 3self.button_label.setAlignment(Qt.AlignCenter)self.xy_label.setAlignment(Qt.AlignCenter)self.global_xy_label.setAlignment(Qt.AlignCenter)self.v_layout = QVBoxLayout()self.v_layout.addWidget(self.button_label)self.v_layout.addWidget(self.xy_label)self.v_layout.addWidget(self.global_xy_label)self.setLayout(self.v_layout)self.resize(300, 300) self.setMouseTracking(True) # 4def mouseMoveEvent(self, QMouseEvent): # 5x = QMouseEvent.x()y = QMouseEvent.y()global_x = QMouseEvent.globalX()global_y = QMouseEvent.globalY()self.xy_label.setText('x:{}, y:{}'.format(x, y))self.global_xy_label.setText('global x:{}, global y:{}'.format(global_x, global_y))def mousePressEvent(self, QMouseEvent): # 6if QMouseEvent.button() == Qt.LeftButton:self.button_label.setText('Left Button Pressed')elif QMouseEvent.button() == Qt.MidButton:self.button_label.setText('Middle Button Pressed')elif QMouseEvent.button() == Qt.RightButton:self.button_label.setText('Right Button Pressed')def mouseReleaseEvent(self, QMouseEvent): # 7if QMouseEvent.button() == Qt.LeftButton:self.button_label.setText('Left Button Released')elif QMouseEvent.button() == Qt.MidButton:self.button_label.setText('Middle Button Released')elif QMouseEvent.button() == Qt.RightButton:self.button_label.setText('Right Button Released')def mouseDoubleClickEvent(self, QMouseEvent): # 8if QMouseEvent.button() == Qt.LeftButton:self.button_label.setText('Left Button Double Clikced')elif QMouseEvent.button() == Qt.MidButton:self.button_label.setText('Middle Button Double Clicked')elif QMouseEvent.button() == Qt.RightButton:self.button_label.setText('Right Button Double Clikced')if __name__ == '__main__':app = QApplication(sys.argv)demo = Demo()demo.show()sys.exit(app.exec_())1. button_label用來顯示鼠標的點擊和釋放動作;
2. xy_label用于記錄鼠標相對于QWidget窗口的坐標;
3. global_xy_label用于記錄鼠標相對于顯示屏屏幕的坐標;
4. setMouseTracking(True)方法可以讓窗口始終追蹤鼠標,否則只能每次等鼠標被點擊后,窗口才會開始記錄鼠標的動作變化;而鼠標釋放后,窗口又會不進行記錄了,這樣比較麻煩。
5. mouseMoveEvent()為鼠標移動時所觸發的響應函數,在函數中,我們通過x()和y()方法獲取鼠標相對于QWidget窗口的坐標,用globalX()和globalY()方法獲取鼠標相對于顯示屏屏幕的坐標;
6. mousePressEvent()為鼠標被按下時所觸發的響應函數,在函數中,我們通過button()方法來確認被按下的鍵,然后用button_label顯示被按下的鍵;
7. mouseReleaseEvent()為鼠標釋放時所觸發的響應函數,同理,在函數中,我們通過button()方法來確認被釋放的鍵,然后用button_label顯示被釋放的鍵;
8. mouseDoubleClickEvent()為鼠標被雙擊時所觸發的響應函數,同理,在函數中,我們通過button()方法來確認被雙擊的鍵,然后用button_label顯示被雙擊的鍵;
運行截圖如下,剛開始坐標都為(0, 0),鼠標也沒有鍵被按下:
之后我們移動鼠標,發現坐標值隨之變化:
按下鼠標左鍵,button_label顯示被按下的鍵:
釋放左鍵后,文本信息變化,顯示被釋放的鍵:
雙擊鼠標左鍵,同樣顯示對應信息:
?17.3 鍵盤事件
每當用戶按下或釋放鍵盤上的任意鍵時都會觸發鍵盤事件:
import sys from PyQt5.QtCore import Qt from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayoutclass Demo(QWidget):def __init__(self):super(Demo, self).__init__()self.pic_label = QLabel(self) # 1self.pic_label.setPixmap(QPixmap('images/keyboard.png'))self.pic_label.setAlignment(Qt.AlignCenter)self.key_label = QLabel('No Key Pressed', self) # 2self.key_label.setAlignment(Qt.AlignCenter)self.v_layout = QVBoxLayout()self.v_layout.addWidget(self.pic_label)self.v_layout.addWidget(self.key_label)self.setLayout(self.v_layout)def keyPressEvent(self, QKeyEvent): # 3if QKeyEvent.key() == Qt.Key_Up:self.pic_label.setPixmap(QPixmap('images/up.png'))self.key_label.setText('Key Up Pressed')elif QKeyEvent.key() == Qt.Key_Down:self.pic_label.setPixmap(QPixmap('images/down.png'))self.key_label.setText('Key Down Pressed')elif QKeyEvent.key() == Qt.Key_Left:self.pic_label.setPixmap(QPixmap('images/left.png'))self.key_label.setText('Key Left Pressed')elif QKeyEvent.key() == Qt.Key_Right:self.pic_label.setPixmap(QPixmap('images/right.png'))self.key_label.setText('Key Right Pressed')def keyReleaseEvent(self, QKeyEvent): # 4self.pic_label.setPixmap(QPixmap('images/keyboard.png'))self.key_label.setText('Key Released')if __name__ == '__main__':app = QApplication(sys.argv)demo = Demo()demo.show()sys.exit(app.exec_())1. pic_label用于設置圖片,先將初始化的圖片設為keyboard.png;
2. key_label用于記錄按鍵狀態;
3. keyPressEvent()為鍵盤某個鍵被按下時所觸發的響應函數,在這個函數中我們判斷被按下的鍵種類,并將pic_label設為相應的箭頭圖片,將key_label設為相應的文本;
4. keyReleasedEvent()在鍵盤上的任意鍵被釋放時所觸發的響應函數,在這個函數中,我們將pic_label設為初始圖片keyboard.png,并將key_label文本設為‘Key Released'。
注:可以在QtAssistant中輸入Qt::Key找到所有鍵盤值:
圖片下載地址:
- keyboard.png: https://www.easyicon.net/download/png/1197696/64/
- up.png: https://www.easyicon.net/download/png/16090/32/
- down.png: https://www.easyicon.net/download/png/6294/32/
- right.png: https://www.easyicon.net/download/png/4515/32/
- left.png: https://www.easyicon.net/download/png/14605/32/
運行截圖如下,初始狀態:
當按下向上鍵后:
釋放后:
關于事件的進階用法,請大家閱讀:
《PyQt5高級編程實戰》事件處理深入應用_la_vie_est_belle的博客-CSDN博客?pyqt5.blog.csdn.net?17.4 小結:
1. 本章一共介紹了三種事件類型:窗口關閉事件、鼠標事件和鍵盤事件,分別是對窗口關閉、鼠標和鍵盤動作的響應。當然事件類型還有很多,之后章節會有涉及;
2. setMouseTracking(True)可以讓窗口時刻追蹤鼠標,而不需要在鼠標被按下時才會進行追蹤;
3. x()和y()獲取鼠標相對于窗口部件的坐標值,而globalX()和globalY()獲取鼠標相對于顯示屏窗口的坐標值;
4. button()方法用于獲取鼠標被按下或釋放的鍵,key()方法用于獲取鍵盤被按下或釋放的鍵。
總結
以上是生活随笔為你收集整理的pyqt5 实现右键自定义_《快速掌握PyQt5》第十七章 事件处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rufus中gpt和mrb磁盘_UEFI
- 下一篇: 东八区转为0时区_初中会考重要知识点:地