如何在QGraphicsScene中不按Ctrl键选择多个项目?

发布于 2024-09-25 08:16:21 字数 156 浏览 5 评论 0原文

在Qt的QGraphicsScene中,如果我想要一个项目,只需单击它,然后单击另一个可选项目将使所选项目取消选择。如果我想选择多个项目,我会使用 Ctrl 键。但这对于某些情况可能不太方便,那么如何在 QGraphicsScene 中不按 Ctrl 键来选择多个项目呢?

In Qt's QGraphicsScene, if I wanna one item, just click it, and click another selectable item will make the selected item to be unselected. If I want to select multiple items, I'd use Ctrl-key. But this maybe not convenient for some cases, then how to select multiple items without pressing Ctrl-key within QGraphicsScene?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨小墨 2024-10-02 08:16:21

您想要更改QGraphicsScene的默认行为,因此您必须创建自己的场景类,继承QGraphicsScene

在您的课程中,您必须至少重新实现 mousePressEvent 并自行处理项目选择。

以下是您可以如何做到这一点(继承的场景类称为GraphicsSelectionScene):

void GraphicsSelectionScene::mousePressEvent(QGraphicsSceneMouseEvent* pMouseEvent) {
    QGraphicsItem* pItemUnderMouse = itemAt(pMouseEvent->scenePos().x(), pMouseEvent->scenePos().y());

    if (!pItemUnderMouse)
        return;
    if (pItemUnderMouse->isEnabled() &&
        pItemUnderMouse->flags() & QGraphicsItem::ItemIsSelectable)
        pItemUnderMouse->setSelected(!pItemUnderMouse->isSelected());
}

以这种方式实现,单击一个项目并选择它(如果尚未选择),否则将取消选择它。

但要小心,实现 mousePressEvent 当然是不够的:如果您不想要默认行为,您还必须处理 mouseDoubleClickEvent

您的场景必须由 QGraphicsView 显示。以下是视图创建自己的场景的示例(MainFrm 类继承 QGraphicsView):

#include "mainfrm.h"
#include "ui_mainfrm.h"
#include "graphicsselectionscene.h"
#include <QGraphicsItem>

MainFrm::MainFrm(QWidget *parent) : QGraphicsView(parent), ui(new Ui::MainFrm) {
    ui->setupUi(this);

    // Create a scene with our own selection behavior
    QGraphicsScene* pScene = new GraphicsSelectionScene(this);
    this->setScene(pScene);

    // Create a few items for testing
    QGraphicsItem* pRect1 = pScene->addRect(10,10,50,50, QColor(Qt::red), QBrush(Qt::blue));
    QGraphicsItem* pRect2 = pScene->addRect(100,-10,50,50);
    QGraphicsItem* pRect3 = pScene->addRect(-200,-30,50,50);

    // Make sure the items are selectable
    pRect1->setFlag(QGraphicsItem::ItemIsSelectable, true);
    pRect2->setFlag(QGraphicsItem::ItemIsSelectable, true);
    pRect3->setFlag(QGraphicsItem::ItemIsSelectable, true);
}

You want to change the default behavior of QGraphicsScene, so you have to create your own scene class, inheriting QGraphicsScene.

In your class, you'll have to reimplement at least mousePressEvent and handle the item selection yourself.

Here is how you could do it (the inherited scene class is called GraphicsSelectionScene) :

void GraphicsSelectionScene::mousePressEvent(QGraphicsSceneMouseEvent* pMouseEvent) {
    QGraphicsItem* pItemUnderMouse = itemAt(pMouseEvent->scenePos().x(), pMouseEvent->scenePos().y());

    if (!pItemUnderMouse)
        return;
    if (pItemUnderMouse->isEnabled() &&
        pItemUnderMouse->flags() & QGraphicsItem::ItemIsSelectable)
        pItemUnderMouse->setSelected(!pItemUnderMouse->isSelected());
}

Implementing this way, clicking on an item with select it if it is not already, or will unselect it otherwise.

But be careful, implement mousePressEvent is certainly not enough : you'll have to handle the mouseDoubleClickEventas well if you don't want the default behavior.

Your scene will have to be displayed by a QGraphicsView. Here is an example of a view creating it's own scene (MainFrm class is inheriting QGraphicsView) :

#include "mainfrm.h"
#include "ui_mainfrm.h"
#include "graphicsselectionscene.h"
#include <QGraphicsItem>

MainFrm::MainFrm(QWidget *parent) : QGraphicsView(parent), ui(new Ui::MainFrm) {
    ui->setupUi(this);

    // Create a scene with our own selection behavior
    QGraphicsScene* pScene = new GraphicsSelectionScene(this);
    this->setScene(pScene);

    // Create a few items for testing
    QGraphicsItem* pRect1 = pScene->addRect(10,10,50,50, QColor(Qt::red), QBrush(Qt::blue));
    QGraphicsItem* pRect2 = pScene->addRect(100,-10,50,50);
    QGraphicsItem* pRect3 = pScene->addRect(-200,-30,50,50);

    // Make sure the items are selectable
    pRect1->setFlag(QGraphicsItem::ItemIsSelectable, true);
    pRect2->setFlag(QGraphicsItem::ItemIsSelectable, true);
    pRect3->setFlag(QGraphicsItem::ItemIsSelectable, true);
}
神也荒唐 2024-10-02 08:16:21

也许这是一个黑客,但它对我有用。在此示例中,您可以使用 Shift 键选择多个项目

void MySceneView::mousePressEvent(QMouseEvent *event)
{
    if (event->modifiers() & Qt::ShiftModifier ) //any other condition
        event->setModifiers(Qt::ControlModifier);

    QGraphicsView::mousePressEvent(event);
}


void MySceneView::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->modifiers() & Qt::ShiftModifier ) //any other condition
        event->setModifiers(Qt::ControlModifier);

    QGraphicsView::mouseReleaseEvent(event);
}

maybe it's a hack but it's works for me. In this example you can select multiple items using shift key

void MySceneView::mousePressEvent(QMouseEvent *event)
{
    if (event->modifiers() & Qt::ShiftModifier ) //any other condition
        event->setModifiers(Qt::ControlModifier);

    QGraphicsView::mousePressEvent(event);
}


void MySceneView::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->modifiers() & Qt::ShiftModifier ) //any other condition
        event->setModifiers(Qt::ControlModifier);

    QGraphicsView::mouseReleaseEvent(event);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文