PyQt5自定義組件功能,包括鼠標事件與鍵盤事件(PyQt5.QtWidgets)

引言

QtWidgets 是PyQT5中負責UI組件的模塊。
要組建自定義組件功能需要QtWidgets中繼承組件,並自定義功能。
本文例子採用鼠標移入Label顯示彈窗。
在這裏插入圖片描述

定義組件類,繼承自QtWidgets

class WatchLabel(QtWidgets.QLabel):#自定義組件WatchLabel,繼承自QLabel
    def __init__(self,parent = None):
        super(WatchLabel, self).__init__(parent)
    

爲自定義組件添加功能

class WatchLabel(QtWidgets.QLabel):#自定義組件WatchLabel,繼承自QLabel
    def __init__(self,parent = None):
        super(WatchLabel, self).__init__(parent)


    def enterEvent(self, *args, **kwargs):#定義鼠標移入事件

    def leaveEvent(self, *args, **kwargs):#定義鼠標移出事件

鼠標事件

處理鼠標事件的頻率不低於鍵盤事件。包括按下、鬆開鼠標按鍵;移動鼠標到特定區域或離開特定區域;更改鼠標指針的形狀,等等。

  1. 按下、鬆開鼠標按鍵
    mousePressEvent (self, event) - 鼠標鍵按下時調用;
    mouseReleaseEvent (self, event) - 鼠標鍵公開時調用;
    mouseDoubieCiickEvent (self, event) - 雙擊鼠標時調用。

  2. 鼠標指針
    要處理鼠標指針的移動,需要重載mouseMoveEvent(self,event)方法。缺省情況下,只有按下鼠標鍵移動時,纔會調用mouseMoveEvent( )。如果要處理包括普通的移動,需要以參數爲True調用setMouseTracking() 方法。如果要處理窗口中鼠標移動的事件,需要調用grabMouse( )方法。

    event對象的pos( )返回值爲相對控件的座標,要轉換成相對父控件或屏幕的座標,需要調用QWidget類的以下方法:
    mapToGlobal (QPoint) - 將窗口座標轉換成屏幕座標;
    mapFromGlobal(QPoint) - 將屏幕座標轉換成窗口座標;
    mapToParent(QPoint) - 將窗口座標轉換成父窗口座標。如果沒有父窗口,則相當於mapToGlobal (QPoint);
    mapFromParent(QPoint) - 將父窗口座標轉換成窗口座標。如果沒有父窗口,則相當於mapFromGlobal(QPoint);
    mapTo (QWidget, QPoint) - 將窗口座標轉換成 QWidget父窗口座標;
    mapFrom (QWidget, QPoint) - 將 QWidget父窗口座標轉換成窗口座標

  3. 鼠標移進和移出控件
    enterEvent (self, event) -鼠標進入控件;
    leaveEvent (self, event) - 鼠標離開控件;

  4. 滾動鼠標
    wheelEvent (self, event)方法可用來處理鼠標滾動事件。event是一個QWheelEvent對象,包含滾輪操作的相關信息。有以下方法可調用:

    angleDelta( ) - 返回QPoint對象,爲滾輪轉過的數值,單位爲1/8度。例如:
    angle=event.angleDelta( ) /8
    angleX=angle.x()
    angleY=angle.y()
    pixelDeita () - 返回QPoint對象,爲滾輪轉過的像素值。
    x() 和 y() - 返回相對於控件的當前鼠標的x,y位置;
    pos() - 返回相對於控件的當前鼠標位置的QPoint對象;
    posF() - 返回相對於控件的當前鼠標位置的QPoinFt對象;
    globalX() 和globalY() - 返回相對於屏幕的當前鼠標的x,y位置;
    globalPos() - 返回相對於屏幕的當前鼠標QPoint位置;
    globalPosF() - 返回相對於屏幕的當前鼠標QPointF位置;
    buttons(),modifiers()和timestamp()的用法參見本文“1.按下、鬆開鼠標按鍵”中的相關內容。
    如果要讓父控件繼續收到滾輪事件,要調用事件的ignore()方法;否則,調用accept()。

  5. 更改鼠標指針形狀
    要修改鼠標進入控件後的形狀,可調用QWidget的下列方法:
    setCursor(QCursor qcr) - 參數qcr爲QCursor對象或 Qtcore.Qt 類的枚舉值,如:ArrowCursor(標準箭頭)、upArrowCursor(向上箭頭)、 CrossCursor(十字光標)、Waitcursor (沙漏),等等。

    setCursor(QtCore.Qt.WaitCursor)

    unsetCursor() - 取消設置的鼠標形狀。
    cursor() - 返回當前鼠標形狀的QCursor對象,。
    使用QApplication類中的以下靜態方法來控制整個應用程序的鼠標形狀:

    setOverrideCursor(QCursor qcr) - 參數qcr爲QCursor對象或 Qtcore.Qt 類的枚舉值。
    restoreOverrideCursor() - 取消全局鼠標形狀設置;
    changeOverrideCursor(QCursor qcr) - 將鼠標形狀設置爲qcr。只有先調用setOverrideCursor( )了,該函數才起作用。
    overrideCursor( ) - 返回當前鼠標形狀的QCursor 對象;
    setOverrideCursor()和restoreOverrideCursor( )通常配合使用。

鍵盤事件

鍵盤事件筆者沒有仔細看過,這裏貼一片介紹的博客

鍵盤事件

建立信號跟槽通信

組件這邊,添加信號跟槽

class WatchLabel(QtWidgets.QLabel):#自定義組件WatchLabel,繼承自QLabel
    def __init__(self,parent = None):
        super(WatchLabel, self).__init__(parent)
	WinShow = QtCore.pyqtSignal()#新建信號,到時候調用的方法就是WinShow,名字可以自己寫
    WinHide = QtCore.pyqtSignal()#新建信號

    def enterEvent(self, *args, **kwargs):#定義鼠標移入事件,鏈接到WinShow信號
        self.WinShow.emit()
    def leaveEvent(self, *args, **kwargs):#定義鼠標移出事件,鏈接到WinHide信號
        self.WinHide.emit()

調用的話,使用connect可以鏈接

#將WinShow與WinHide連接到函數上,注意這裏函數BoxWinShow不是調用,是鏈接,所有沒有(),寫了會無法識別
        self.label.WinShow.connect(self.BoxWinShow)
        self.label.WinHide.connect(self.BoxWinHide)
    #函數,顯示彈窗窗口    
    def BoxWinShow(self):
        self.boxWin = BoxWin()
        self.boxWin.show()
     #函數,隱藏彈窗窗口
    def BoxWinHide(self):
        self.boxWin = BoxWin()
        self.boxWin.hide()

完整代碼

github地址

兩個文件

#MainWin.py 
#主窗口文件,負責邏輯
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QAction
from Ui_Form import *
class MainWin(QMainWindow,Win_Form):
    def __init__(self,parent=None):
        super(QMainWindow,self).__init__(parent)
        self.setupUi(self)
        #將WinShow與WinHide連接到函數上
        self.label.WinShow.connect(self.BoxWinShow)
        self.label.WinHide.connect(self.BoxWinHide)
    def BoxWinShow(self):
        self.boxWin = BoxWin()
        self.boxWin.show()
    def BoxWinHide(self):
        self.boxWin = BoxWin()
        self.boxWin.hide()
class BoxWin(QMainWindow,Box_Form):
    def __init__(self,parent=None):
        super(QMainWindow,self).__init__(parent)
        self.setupUi(self)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWin()
    win.show()
    sys.exit(app.exec_())
#Ui_Form.py
#窗口Ui文件,負責控制樣式QSS
from PyQt5 import QtCore, QtGui, QtWidgets


class WatchLabel(QtWidgets.QLabel):#自定義組件WatchLabel,繼承自QLabel
    def __init__(self,parent = None):
        super(WatchLabel, self).__init__(parent)
    WinShow = QtCore.pyqtSignal()#新建信號,到時候調用的方法就是WinShow,名字可以自己寫
    WinHide = QtCore.pyqtSignal()#新建信號

    def enterEvent(self, *args, **kwargs):#定義鼠標移入事件,鏈接到WinShow信號
        self.WinShow.emit()
    def leaveEvent(self, *args, **kwargs):#定義鼠標移出事件,鏈接到WinHide信號
        self.WinHide.emit()

class Win_Form(object):#主窗口UI格式
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(453, 327)
        # 注意這裏使用的是自定義的WatchLabel,而不是QtWidgets.QLabel,這樣,這個Label就有了鼠標移入移出事件
        self.label = WatchLabel(Form)
        self.label.setGeometry(QtCore.QRect(20, 20, 161, 51))
        self.label.setObjectName("label")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "這是一個組件,移入會有彈窗"))

class Box_Form(object):#彈窗窗口UI格式
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(354, 512)
        Form.setMinimumSize(QtCore.QSize(354, 512))
        Form.setMaximumSize(QtCore.QSize(354, 512))
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(0, 0, 354, 512))
        self.label.setMinimumSize(QtCore.QSize(354, 512))
        self.label.setMaximumSize(QtCore.QSize(354, 512))
        self.label.setText("")
        self.label.setPixmap(QtGui.QPixmap("./彈窗.PNG"))
        self.label.setObjectName("label")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))


參考鏈接

PyQt5編程-鼠標事件
PyQt5的鍵盤事件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章