- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想放一个 QWidget
成QGraphicsView
并使用 QGraphicsProxyWidget
使小部件可选和可移动.
(这非常适用于 QGraphicsRectItem
、 QGraphicItem
等)
这是我目前使用的代码:
// Create new QGraphicsScene and assign to graphicsView
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
// Create widget and add to scene
MyWidget *widget = new MyWidget;
QGraphicsProxyWidget *proxy = scene->addWidget(widget);
// Make selectable
proxy->setFlag(QGraphicsItem::ItemIsSelectable, true);
// Make movable
proxy->setFlag(QGraphicsItem::ItemIsMovable, true);
最佳答案
我问自己和你在这里做的一样的问题。在我继续解决这个问题几个小时后我想出的解决方案之前,我不得不提到一般如果您想在场景中包含大量小部件,则将小部件添加到场景中不是一个好主意 .您可以阅读有关此问题的信息 here .
现在回到正轨。以下是在尝试实现您想要的事情时出现的一些重大问题:
mouseMove()
和 mouseHover()
你的小部件代理,你会搞砸小部件的 UI 组件的行为方式。 QGraphicsProxyWidget
与
QGraphicsItem
!
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SceneWithMovableProxies</class>
<widget class="QWidget" name="SceneWithMovableProxies">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>SceneWithMovableProxies</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView"/>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
main.cpp
#include "scenewithmovableproxies.hpp"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SceneWithMovableProxies w;
w.show();
return a.exec();
}
scenewithmovableproxies.hpp
#ifndef SCENEWITHMOVABLEPROXIES_HPP
#define SCENEWITHMOVABLEPROXIES_HPP
#include <QWidget>
#include <QPoint>
namespace Ui {
class SceneWithMovableProxies;
}
class SceneWithMovableProxies : public QWidget
{
Q_OBJECT
public:
explicit SceneWithMovableProxies(QWidget *parent = 0);
~SceneWithMovableProxies();
private:
Ui::SceneWithMovableProxies *ui;
void addWidgetToScene(QPoint initPos);
};
#endif // SCENEWITHMOVABLEPROXIES_HPP
scenewithmovableproxies.cpp
#include "scenewithmovableproxies.hpp"
#include "ui_scenewithmovableproxies.h"
#include "scenewidgetitem.hpp"
#include <QGraphicsProxyWidget>
SceneWithMovableProxies::SceneWithMovableProxies(QWidget *parent) :
QWidget(parent),
ui(new Ui::SceneWithMovableProxies)
{
ui->setupUi(this);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
ui->graphicsView->setScene(new QGraphicsScene(this));
// Add widget proxies + their parenting graphics items to scene
addWidgetToScene(QPoint(10, 10));
addWidgetToScene(QPoint(300, 100));
addWidgetToScene(QPoint(200, 200));
}
SceneWithMovableProxies::~SceneWithMovableProxies()
{
delete ui;
}
void SceneWithMovableProxies::addWidgetToScene(QPoint initPos)
{
// Create a widget
SceneWidgetItem *widget = new SceneWidgetItem();
// Create the graphics item that will be used to move the widget around the screen as well as be selectable (for example in case we want to delete a widget that is in the scene)
// Depending on the position of the graphics item relative to its widget proxy you can adjust the size and location of both
QGraphicsRectItem *proxyControl = ui->graphicsView->scene()->addRect(initPos.x(), initPos.y(), widget->width(), 20, QPen(Qt::black), QBrush(Qt::darkGreen)); // widget->width() works properly here because of the resize(layout->sizeHint()) that we have used inside it
proxyControl->setFlag(QGraphicsItem::ItemIsMovable, true);
proxyControl->setFlag(QGraphicsItem::ItemIsSelectable, true);
// Create the proxy by adding the widget to the scene
QGraphicsProxyWidget * const proxy = ui->graphicsView->scene()->addWidget(widget);
// In my case the rectangular graphics item is supposed to be above my widget so the position of the widget is shifted along the Y axis based on the height of the rectangle of that graphics item
proxy->setPos(initPos.x(), initPos.y()+proxyControl->rect().height());
proxy->setParentItem(proxyControl);
// proxyControl->setRotation(45); // Because the widget is a child of the graphics item if we do some sort of transformation to it, the change will be propagated to the widget too!
}
scenewidgetitem.hpp
#ifndef SCENEWIDGETITEM_HPP
#define SCENEWIDGETITEM_HPP
#include <QWidget>
#include <QVBoxLayout>
#include <QCheckBox>
#include <QComboBox>
#include <QLabel>
#include <QPushButton>
class SceneWidgetItem : public QWidget
{
Q_OBJECT
QVBoxLayout *layout;
QLabel *label;
QCheckBox *checkbox;
QComboBox *combobox;
QPushButton *resetButton;
public:
explicit SceneWidgetItem(QWidget *parent = 0);
~SceneWidgetItem();
signals:
public slots:
void reset();
};
#endif // SCENEWIDGETITEM_HPP
scenewidgetitem.cpp
#include "scenewidgetitem.hpp"
// Create a widget with whichever UI components you like
SceneWidgetItem::SceneWidgetItem(QWidget *parent) : QWidget(parent)
{
layout = new QVBoxLayout(this);
checkbox = new QCheckBox("Enable proxy", this);
checkbox->setChecked(true);
combobox = new QComboBox(this);
combobox->addItem("---");
combobox->addItem("Item 1");
combobox->addItem("Item 2");
combobox->addItem("Item 3");
label = new QLabel(this);
label->setText(combobox->itemText(0));
resetButton = new QPushButton("Reset", this);
// Maybe add some signals :P
connect(checkbox, SIGNAL(toggled(bool)), combobox, SLOT(setEnabled(bool)));
connect(checkbox, SIGNAL(toggled(bool)), resetButton, SLOT(setEnabled(bool)));
connect(resetButton, SIGNAL(clicked(bool)), this, SLOT(reset()));
connect(combobox, SIGNAL(currentIndexChanged(QString)), label, SLOT(setText(QString)));
layout->addWidget(checkbox);
layout->addWidget(label);
layout->addWidget(resetButton);
layout->addWidget(combobox);
// Resizing the widget to its layout's content is very important. If
// you don't do that the parenting graphics item will not visually fit
// to its child widget and you will get a mess
resize(layout->sizeHint());
setLayout(layout);
}
SceneWidgetItem::~SceneWidgetItem()
{
}
void SceneWidgetItem::reset()
{
combobox->setCurrentIndex(0);
label->setText("---");
}
以下是一些截图:
QGraphicsItem
的性质(以及
QGraphicsProxyWidget
)有一些问题最烦人的是重叠
QGraphicsProxyWidget
也可以使用
QGraphicsItem
功能
collisionWithItem(...)
您可以实现一种机制来处理这种情况。因为我是新来的
QGraphicsScene
所有这一切(2 天前开始,同时在 SO :D 上回答问题时开始)在
QGraphicsScene
中可能存在某种集成机制。自己来处理这个。
QPainter::Antialiasing
) 还要糟糕。
QGraphicsItem
s 并且节点配置本身部分外包给了
QGraphicsViewer
的外部。小部件。您可以使用我上面描述的设计,并根据您以后想要做的事情添加更多内容。多个
QGraphicItem
s 也可以附加到小部件代理。您可以对此感到疯狂,但请记住,这会对性能产生影响(请一次又一次地阅读我在答案开头链接的博客文章)。
关于c++ - 使 QGraphicsProxyWidget 可移动和可选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15413564/
我有一个 QGraphicsScene,其中我在 QGraphicsProxyWidgets 中添加了 QPushButtons。有没有办法显示这些按钮的工具提示? setToolTip 可以工作,但
我正在使用 QGraphicsScene 并通过隐式创建向其添加常规小部件(QLineEdit、QComboBox 等) QGraphicsProxyWidget 对象: m_pLineEdit =
我尝试在场景中添加 QPushButton,但是当我尝试将 QGraphicsProxyWidget 添加到场景时,它崩溃了。 所以这是.cpp: #include "upgradecromagnon
我想放一个 QWidget成QGraphicsView并使用 QGraphicsProxyWidget 使小部件可选和可移动. (这非常适用于 QGraphicsRectItem 、 QGraphic
以下代码基于Graphics View Framework的文档。我在 QGraphicsScene 中嵌入了 QLineEdit 并运行程序。当我右键单击场景中的线编辑时,我得到一个剪裁的上下文菜单
我有一个 QGraphicsScene,我在其中显示一些 QGraphicsProxyWidgets,例如 QComboBox。在初始状态下,一切正常: 但是,一旦显示了组合框的弹出部分,它就不是在场
我正在Qt 5 上国际象棋项目。我将棋盘创建为 QWidget,现在我想添加动画棋子。这就是为什么我想在图形 View 上添加我的棋盘。我查阅了 Qt 文档 和其他几个网站。并编写了以下代码:
我有一个包含多个自定义 QGraphicsItem 的 QGraphicsScene。每个项目都包含一个 QGraphicsProxyWidget,它本身包含业务逻辑所需的任何小部件。代理有一个应用到
我试图用鼠标移动 QGraphicsView 上的按钮,但不是工作,有人可以帮助我解决我的问题吗? int main(int argc, char *argv[]) { QApplication
我是一名优秀的程序员,十分优秀!