如果通过 QGraphicsProxyWidget 在 QGraphicsView 中,QCombobox 将不会打开

问题描述 投票:0回答:1

我对 PySide 有点陌生,所以请原谅任何错误。在 PySide6 中,我想将组合框放入 QGraphicsRectItem 中,以显示在 QGraphicsView 内。组合框显示良好并突出显示正常,但其弹出窗口永远不会打开,因此我看不到添加到其中的选项。我使用同样的技术来放置 QLineEdits 和 QCheckboxes,它们工作正常。知道出了什么问题吗?我在 Windows 11 上运行 Python 3.9.13、PySide6 6.7.0。这是我的代码:

import sys
from PySide6.QtWidgets import (
    QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem,QGraphicsProxyWidget, QComboBox, QVBoxLayout, QGraphicsItem, QCheckBox, QLineEdit
)
from PySide6.QtCore import Qt, QRectF, QObject


class StepView(QGraphicsRectItem, QObject):
    def __init__(self, rect, parent=None):
        QGraphicsRectItem.__init__(self, rect, parent)
        QObject.__init__(self)

        # Create the combobox and add options
        self.comboBox = QComboBox()
        self.comboBox.addItems(["Option 1", "Option 2", "Option 3"])

        # Embed the combobox in the graphics item using a proxy widget
        self.proxy = QGraphicsProxyWidget(self)
        self.proxy.setWidget(self.comboBox)

        # Position the combobox within the rect item
        combo_box_width = self.comboBox.sizeHint().width()
        combo_box_height = self.comboBox.sizeHint().height()
        self.proxy.setPos((rect.width() - combo_box_width) / 2, (rect.height() - combo_box_height) / 2)



app = QApplication(sys.argv)
scene = QGraphicsScene()
view = QGraphicsView(scene)
view.setWindowTitle("StepView Example")
view.setGeometry(100, 100, 500, 500)

# Create a StepView item
step_view = StepView(QRectF(0, 0, 100, 100))
scene.addItem(step_view)
view.show()
sys.exit(app.exec())
python pyside6 qcombobox
1个回答
0
投票

我最近遇到了和你一样的问题。以下解决方案已在 Windows 11 上测试并且有效。可以进一步改进以更好的格式显示下拉列表。基本上没有什么对我有用,我最接近的解决方案是创建一个列表小部件并向其中添加组合框项目,每当在组合框中拦截左键单击时,将重新获得单击的信号,这将触发下拉列表小部件显示,并且选择的结果将设置为组合框。列表小部件的位置可以改进。

import sys
from PySide6.QtCore import QPointF, QRectF, Qt, Signal
from PySide6.QtGui import QMouseEvent
from PySide6.QtWidgets import (
    QApplication,
    QComboBox,
    QGraphicsProxyWidget,
    QGraphicsRectItem,
    QGraphicsScene,
    QGraphicsView,
    QListWidget,
)


class CustomComboBox(QComboBox):
    # Define a custom signal (as combobox does not have clicked signal, but combobox.view() does, which doesnt help)
    clicked = Signal()

    def mousePressEvent(self, event: QMouseEvent):
        super().mousePressEvent(event)
        if event.button() == Qt.LeftButton:
            self.clicked.emit()  # Emit the clicked signal on left mouse press


class StepView(QGraphicsRectItem):
    def __init__(self, rect, parent=None):
        super(StepView, self).__init__(rect, parent)

        # Create the custom combobox and add options
        self.comboBox = CustomComboBox()
        self.comboBox.addItems(["Option 1", "Option 2", "Option 3"])

        # Embed the combobox in the graphics item using a proxy widget
        self.proxy = QGraphicsProxyWidget(self)
        self.proxy.setWidget(self.comboBox)
        self.proxy.setPos(
            (rect.width() - self.comboBox.width()) / 2,
            (rect.height() - self.comboBox.height()) / 2,
        )

        # Connect the custom clicked signal to show the dropdown
        self.comboBox.clicked.connect(self.showCustomDropdown)

    def showCustomDropdown(self):
        self.dropdown = QListWidget()
        for i in range(self.comboBox.count()):
            self.dropdown.addItem(self.comboBox.itemText(i))

        # Position the dropdown
        scene_pos = self.proxy.mapToScene(QPointF(0, self.comboBox.height()))
        global_pos = self.proxy.scene().views()[0].mapToGlobal(scene_pos.toPoint())
        self.dropdown.move(global_pos)
        self.dropdown.setMinimumWidth(self.comboBox.width())
        self.dropdown.currentItemChanged.connect(self.onItemSelected)
        self.dropdown.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint)
        self.dropdown.show()

    def onItemSelected(self, item):
        if item:
            self.comboBox.setCurrentText(item.text())
        self.dropdown.close()  # Close the dropdown


app = QApplication(sys.argv)
scene = QGraphicsScene()
view = QGraphicsView(scene)
view.setWindowTitle("StepView Example")
view.setGeometry(100, 100, 500, 500)

# Create a StepView item
step_view = StepView(QRectF(0, 0, 100, 100))
scene.addItem(step_view)
view.show()
sys.exit(app.exec())
© www.soinside.com 2019 - 2024. All rights reserved.