Pyside QDialog & EventFilter === ###### tags: `Python` ### 緣起 1. 按下Mainwindow的button創建一個dialog,並傳signal給dialog :::danger 關閉dialog時不會將自己砍掉,所以關掉後再次點擊會傳出兩個signal給兩個同名的人 ::: 2. 偵測滑鼠點擊Dialog的位置和元件,以做不同動作 :::danger 卻發現label和frame沒有default的clicked signal可以用 ::: ### 解法 1. 偵測dialog關閉事件,若發生就把自己砍掉 ```python '''直接寫在dialog的class裡''' def closeEvent(self, event): self.deleteLater() print("X is clicked") ``` 2. 需要對dialog要偵測的元件註冊EventFilter ```python '''都寫在dialog class裡''' for w in self.findChildren(QtWidgets.QWidget)+[self]: w.installEventFilter(self) self.i = 0 def eventFilter(self, obj, event): if event.type() == QtCore.QEvent.MouseButtonPress: if event.buttons() & QtCore.Qt.LeftButton: ... return super(RegAnalyzer, self).eventFilter(obj, event) ``` **坑** * mainwindow 開啟Dialog有兩種call法 - show()和exec() show()開啟後,主執行緒還是在mainwindow這邊; exec()執行後則無法操控mainwindow,只能控制dialog * 網上找到的註冊eventfilter方法都是先宣告dialog,然後直接在main function對其做註冊(如下) ```python class MouseDetector(QtCore.QObject): i = 0 def eventFilter(self, watched: QtCore.QObject, event: QtCore.QEvent) -> bool: if event.type() == event.MouseButtonPress: self.i += 1 print(f"{self.i}: Mouse Pressed") print('mouse pressed', watched.objectName()) return super().eventFilter(watched, event) app = dialog() mouseFilter = MouseDetector() app.installEventFilter(mouseFilter) ``` * 但這個方法對show()或exec()生成的視窗無效,因此必須把事件寫在dialog裡面,如"解法2"所提。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up