现在,我正在学习QGraphicsView。我按照诺基亚从2011年开始的教程(YouTube:Qt DevDays 2011,Advanced Qt -A Deep Dive 1/6)。这是一个非常基本的演示,显示了一个房子(由QRect和QPolygon制成),如果点击它就会转过来。在房子的背面有一些小部件(例如QCombobox),它们由QGraphicsItemGroup保存在QGraphicsProxyWidget中。现在我面临的问题是,自Qt 4.7以来,类QGraphicItemsGroup不再支持标志“setHandlesChildEvents(False)”。
由于QGraphicsItemGroup将处理所有事件,我如何实现QGraphicsItem组不会阻止子项的事件,以及让子项处理它自己的事件?
提前感谢您的帮助!
main_house.py
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsView
from PyQt5.QtCore import Qt
import sys
from House.house import House
app = QApplication([])
scene = QGraphicsScene()
house_1 = House(Qt.blue, Qt.yellow)
scene.addItem(house_1)
scene.setSceneRect(0, 0, 500, 500)
view = QGraphicsView(scene)
view.show()
view.resize(600, 600)
sys.exit(app.exec_())
house.py
from PyQt5.QtWidgets import QGraphicsItemGroup,QGraphicsProxyWidget,QGraphicsRectItem,QGraphicsPolygonItem, \
QWidget, QVBoxLayout, QLabel, QComboBox, QPushButton
from PyQt5.QtCore import QTimeLine, QPointF, QRectF, Qt
from PyQt5.QtGui import QColor, QPolygonF, QTransform
class House(QGraphicsItemGroup):
def __init__(self, roofcolor: QColor, facadecolor: QColor, parent=None):
super(House, self).__init__(parent)
self._front = True
self._timeline = None
self._graphics = None
self._configpage = None
self._facade = None
self._roof = None
self.roof_polygon = QPolygonF()
self.roof_polygon << QPointF(0, 200) << QPointF(100, 0) << QPointF(200, 200)
self.body_rect = QRectF(0, 200, 200, 200)
self.create_roof(roofcolor)
self.create_front(facadecolor)
self.create_back(roofcolor, facadecolor)
# ==========================
# self.setHandlesChildEvents(False) # obsolete since Qt 4.7
# ==========================
def mousePressEvent(self, event):
if not self._timeline:
self._timeline = QTimeLine(1000)
self._timeline.setCurveShape(QTimeLine.EaseInOutCurve)
self._timeline.valueChanged.connect(self.rotate_house)
self._timeline.finished.connect(self.reset)
self._timeline.start()
def reset(self):
self._timeline = None
def rotate_house(self, pos):
angle = int(pos * 180)
if self._front is True:
angle += 180
transform = QTransform()
transform.translate(100, 0)
transform.rotate(angle, Qt.YAxis)
transform.translate(-100, 0)
self.setTransform(transform)
if pos == 1.0:
self._front = not self._front
config = angle < 90 or angle >= 270
self._configpage.setVisible(config)
self._facade.setVisible(not config)
def update_roof_color(self):
combo = self.sender()
color = combo.itemData(combo.currentIndex()).value()
self._roof.setBrush(color)
def update_house_color(self):
combo = self.sender()
color = combo.itemData(combo.currentIndex()).value()
self._facade.setBrush(color)
def create_roof(self, color: QColor):
self._roof = QGraphicsPolygonItem(self.roof_polygon)
self.addToGroup(self._roof)
self._roof.setBrush(color)
def create_front(self, color: QColor):
self._facade = QGraphicsRectItem(self.body_rect)
self._facade.setBrush(color)
self.addToGroup(self._facade)
def create_back(self, roof_color: QColor, facade_color: QColor):
self._configpage = QGraphicsProxyWidget()
self._configpage.setWidget(self.create_config_widget(roof_color, facade_color))
self._configpage.setGeometry(self.body_rect)
self.addToGroup(self._configpage)
self._configpage.hide()
# ==== Problem: Widgets (comboboxes) do not receive events ====
def create_config_widget(self, roof_color: QColor, facade_color: QColor) -> QWidget:
res = QWidget()
layout = QVBoxLayout(res)
label = QLabel('Roof color:')
layout.addWidget(label)
self.roof_combo = self.create_color_combobox(roof_color) # combobox does not receive events
layout.addWidget(self.roof_combo)
self.roof_combo.activated.connect(self.update_roof_color)
label = QLabel('House color:')
layout.addWidget(label)
self.facade_combo = self.create_color_combobox(facade_color)
layout.addWidget(self.facade_combo)
self.facade_combo.activated.connect(self.update_house_color)
bt = QPushButton('Test')
bt.setCheckable(True)
layout.addWidget(bt)
layout.addStretch(1)
return res
def create_color_combobox(self, color: QColor) -> QComboBox:
res = QComboBox()
res.addItem('red', QColor(Qt.red))
res.addItem('blue', QColor(Qt.blue))
res.addItem('green', QColor(Qt.green))
res.addItem('white', QColor(Qt.white))
res.setCurrentIndex(res.findData(color))
return res