Issue
According to documentation, in order to unset an attribute, I need to pass False
as the second parameter to setAttribute
method of a widget. I am already doing that, but for some reason window stays transparent for mouse events.
Here is a minimal reproducible example:
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt6.QtCore import Qt
class Main(QWidget):
def __init__(self):
super().__init__()
self.resize(400, 400)
self.setWindowTitle('Main')
self.state = False
self.button = QPushButton(f'Secondary window can be clicked through: {self.state}')
self.button.clicked.connect(self.button_click)
self.layout = QVBoxLayout()
self.layout.addWidget(self.button)
self.setLayout(self.layout)
self.secondary = Secondary()
def button_click(self):
self.state = not self.state
self.button.setText(f'Secondary window can be clicked through: {self.state}')
self.secondary.set_click_through_state(self.state)
class Secondary(QWidget):
def __init__(self):
super().__init__()
self.resize(400, 400)
self.setWindowOpacity(0.8)
self.setWindowTitle('Secondary')
def set_click_through_state(self, state: bool):
print('Received new state:', state)
self.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, on=state)
self.hide()
if state:
self.setWindowFlags(
self.windowFlags()
| Qt.WindowType.FramelessWindowHint
| Qt.WindowType.WindowStaysOnTopHint
)
else:
self.setWindowFlags(
self.windowFlags()
& ~Qt.WindowType.FramelessWindowHint
& ~Qt.WindowType.WindowStaysOnTopHint
)
self.show()
print('Attribute is set:', self.testAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Main()
main.show()
main.secondary.show()
sys.exit(app.exec())
Tested on Windows 10 / Python 3.10 / PyQt6.
Solution
Turns out that setting WA_TransparentForMouseEvents
attribute to a widget also adds a WindowTransparentForInput
flag to it. I am not sure why, but this flag is not removed when unsetting an attribute.
Issue resolved by simply removing WindowTransparentForInput
flag from window:
widget.setWindowFlags(
widget.windowFlags() & ~Qt.WindowType.WindowTransparentForInput
)
Answered By - Artur Krapivkin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.