Reputation: 617
To this question I am referring to the answer from @Kuba Ober Draw Rectangular overlay on QWidget at click
My problem: I dont know how to "translate" the C++ (or C?) into Python. :-(
Thus I ask this "duplicated" question again, and wish anyone would help to rewrite the code to achieve the overlay effect in PyQt5.
As an example, I prepare here some code:
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class MyApp(QWidget):
def __init__(self):
super(MyApp, self).__init__()
self.initUI()
def initUI(self):
self.text = "hello world"
self.setGeometry(100, 100, 400, 300)
self.setWindowTitle('Draw Demo')
self.btn = QPushButton("Butten should be overlayed", self)
self.btn.setFixedSize(200, 200)
self.btn.move(40, 40)
self.show()
def paintEvent(self, event):
qp = QPainter()
qp.begin(self)
qp.setPen(QColor(Qt.red))
qp.setFont(QFont('Arial', 20))
qp.drawText(10, 50, "hello Python")
qp.setPen(QColor(Qt.blue))
qp.drawLine(10, 100, 100, 100)
qp.drawRect(10, 150, 150, 100)
qp.setPen(QColor(Qt.red))
qp.drawEllipse(100, 50, 100, 50)
# qp.drawPixmap(220, 10, QPixmap("python.jpg"))
qp.fillRect(200, 175, 150, 100, QBrush(Qt.SolidPattern))
qp.end()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
Target is: Let the Button shown in the background (overlayed by QPainter), but it is transparent to mouse event. Thus I could click the button, even though it is covered by QPainter.
Any help will be highly appreciated!
Upvotes: 0
Views: 2146
Reputation: 244282
The translation from C ++ to Python is simple if we know the equivalences and differences between both languages as I show below:
overLay.py
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class OverLay(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.setAttribute(Qt.WA_NoSystemBackground)
self.setAttribute(Qt.WA_TransparentForMouseEvents)
def paintEvent(self, event):
painter = QPainter(self)
painter.fillRect(self.rect(), QColor(80, 80, 255, 128))
class Filter(QObject):
def __init__(self, *args, **kwargs):
QObject.__init__(self, *args, **kwargs)
self.m_overlay = None
self.m_overlayOn = None
def eventFilter(self, obj, event):
if not obj.isWidgetType():
return False
if event.type() == QEvent.MouseButtonPress:
if not self.m_overlay:
self.m_overlay = OverLay(obj.parentWidget())
self.m_overlay.setGeometry(obj.geometry())
self.m_overlayOn = obj
self.m_overlay.show()
elif event.type() == QEvent.Resize:
if self.m_overlay and self.m_overlayOn == obj:
self.m_overlay.setGeometry(obj.geometry())
return False
if __name__ == '__main__':
app = QApplication(sys.argv)
filt = Filter()
window = QWidget()
lay = QHBoxLayout(window)
for text in ( "Foo", "Bar", "Baz "):
label = QLabel(text)
lay.addWidget(label)
label.installEventFilter(filt)
window.setMinimumSize(300, 250)
window.show()
sys.exit(app.exec_())
Understanding what you want to do in your widget you must use the following code:
main.py
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from overlay import Filter
class MyApp(QWidget):
def __init__(self):
super(MyApp, self).__init__()
self.initUI()
def initUI(self):
self.text = "hello world"
self.setGeometry(100, 100, 400, 300)
self.setWindowTitle('Draw Demo')
self.btn = QPushButton("Butten should be overlayed", self)
self.btn.setFixedSize(200, 200)
self.btn.move(40, 40)
filt = Filter(self)
self.btn.installEventFilter(filt)
self.show()
[...]
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
Upvotes: 1