我正在使用带有QPaintEvent的叠加层来绘制其他小部件。我仍然在下面的按钮上注册鼠标事件。当我使用WA_TransparentForMouseEvents标志调用raise()时,我再次获得了对按钮的控制权,但是,当然,由于不再注册任何鼠标事件,因此丢失了paintevent。我在这里有什么选择?
class Overlay(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Overlay, self).__init__(parent)
self.hotBox = parent
self.resize(self.hotBox.width, self.hotBox.height)
def paintEvent(self, event):
#args: [QEvent]
if any ([self.hotBox.name=="main", self.hotBox.name=="viewport"]):
self.raise_()
self.setWindowFlags(QtCore.Qt.WA_TransparentForMouseEvents)
#Initialize painter
painter = QtGui.QPainter(self)
pen = QtGui.QPen(QtGui.QColor(115, 115, 115), 3, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)
painter.setPen(pen)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
painter.setBrush(QtGui.QColor(115, 115, 115))
painter.drawEllipse(self.hotBox.point, 5, 5)
#perform paint
if self.hotBox.mousePosition:
mouseX = self.hotBox.mousePosition.x()
mouseY = self.hotBox.mousePosition.y()
line = QtCore.QLine(mouseX, mouseY, self.hotBox.point.x(), self.hotBox.point.y())
painter.drawLine(line)
painter.drawEllipse(mouseX-5, mouseY-5, 10, 10)
答案 0 :(得分:1)
如果您要使用事件mouseXXXEvent
创建覆盖,则必须使用eventFilter
,为此,我基于this answer中@KubaOber的解决方案,添加了更多功能:< / p>
import sys
from PySide2 import QtCore, QtGui, QtWidgets
class Overlay(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Overlay, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_NoSystemBackground)
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
self.start_line, self.end_line = QtCore.QPoint(), QtCore.QPoint()
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.fillRect(self.rect(), QtGui.QColor(80, 80, 255, 128))
if not self.start_line.isNull() and not self.end_line.isNull():
painter.drawLine(self.start_line, self.end_line)
def mousePressEvent(self, event):
self.start_line = event.pos()
self.end_line = event.pos()
self.update()
def mouseMoveEvent(self, event):
self.end_line = event.pos()
self.update()
def mouseReleaseEvent(self, event):
self.start_line = QtCore.QPoint()
self.end_line = QtCore.QPoint()
class OverlayFactoryFilter(QtCore.QObject):
def __init__(self, parent=None):
super(OverlayFactoryFilter, self).__init__(parent)
self.m_overlay = None
def setWidget(self, w):
w.installEventFilter(self)
if self.m_overlay is None:
self.m_overlay = Overlay()
self.m_overlay.setParent(w)
def eventFilter(self, obj, event):
if not obj.isWidgetType():
return False
if event.type() == QtCore.QEvent.MouseButtonPress:
self.m_overlay.mousePressEvent(event)
elif event.type() == QtCore.QEvent.MouseButtonRelease:
self.m_overlay.mouseReleaseEvent(event)
elif event.type() == QtCore.QEvent.MouseMove:
self.m_overlay.mouseMoveEvent(event)
elif event.type() == QtCore.QEvent.MouseButtonDblClick:
self.m_overlay.mouseDoubleClickEvent(event)
elif event.type() == QtCore.QEvent.Resize:
if self.m_overlay and self.m_overlay.parentWidget() == obj:
self.m_overlay.resize(obj.size())
elif event.type() == QtCore.QEvent.Show:
self.m_overlay.raise_()
return super(OverlayFactoryFilter, self).eventFilter(obj, event)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
factory = OverlayFactoryFilter()
w = QtWidgets.QWidget()
factory.setWidget(w)
button = QtWidgets.QPushButton("Press me", w)
w.show()
sys.exit(app.exec_())