我有一个QListWidget
和一个QGraphicsView
两个子类来覆盖他们的一些成员。我准备了一个最小的可验证示例来显示我遇到的问题。
从QListWidget
我可以拖放由 a 表示的特定字段QTableWidget
并将它们放入 aQGraphicsView
中,为了做到这一点,我正在使用QGraphicsProxyWidget
如下所示的方法。
值得一提的是,QGraphicsRectItem
它用于在绿色周围移动QTableWidget
以及调整其尺寸。
问题:从那里拖动QListWidget
不是问题。但是放入QGraphicsView
是一个问题,因为如您所见,QGraphicsRectItem
它就在QTableWidget
.
为了完整性,可以在此处和下方找到最小可验证示例:
但是,只要我用 的尺寸触摸调整本身的QSizeGrip
右下角:QGraphicsProxyWidget
QGraphicsRectItem
QTableWidgetItem
在最小可验证示例下方:
主文件
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
#include "scene.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
Scene *mScene;
};
#endif // MAINWINDOW_H
主窗口.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mScene = new Scene;
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
ui->graphicsView->setScene(mScene);
ui->graphicsView->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
选项列表.h
#ifndef OPTIONLIST_H
#define OPTIONLIST_H
#include <QListWidget>
class OptionList : public QListWidget {
public:
OptionList(QWidget *parent = nullptr);
protected:
void startDrag(Qt::DropActions supportedActions);
};
#endif // OPTIONLIST_H
选项列表.cpp
#include "optionlist.h"
#include <QDrag>
OptionList::OptionList(QWidget *parent) : QListWidget(parent) {
setDragEnabled(true);
setDropIndicatorShown(true);
setSelectionMode(QAbstractItemView::SingleSelection);
setDefaultDropAction(Qt::CopyAction);
setViewMode(QListView::ListMode);
for (const QString &workspaceTree : {"Images", "Path", "Connection"}) {
QListWidgetItem *img = new QListWidgetItem;
img->setText(workspaceTree);
img->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable |
Qt::ItemIsDragEnabled);
addItem(img);
}
}
void OptionList::startDrag(Qt::DropActions supportedActions) {
if (supportedActions & Qt::CopyAction) {
QList<QListWidgetItem *> m_items = selectedItems();
if (m_items.isEmpty())
return;
QMimeData *data = mimeData(m_items);
QDrag *drag = new QDrag(this);
QPixmap pixmap("/home/Icon_icon.png");
drag->setPixmap(pixmap);
drag->setMimeData(data);
drag->setHotSpot(pixmap.rect().center());
drag->exec(Qt::CopyAction);
} else
QListWidget::startDrag(supportedActions);
}
customtablewidget.h
#ifndef CUSTOMTABLEWIDGET_H
#define CUSTOMTABLEWIDGET_H
#include <QTableWidget>
#include <QResizeEvent>
class CustomTableWidget : public QTableWidget
{
Q_OBJECT
public:
CustomTableWidget(QWidget *parent = Q_NULLPTR) : QTableWidget(parent){}
void resizeEvent(QResizeEvent *event);
signals:
void sizeChanged();
};
#endif // CUSTOMTABLEWIDGET_H
customtablewidget.cpp
#include "customtablewidget.h"
void CustomTableWidget::resizeEvent(QResizeEvent *event)
{
QTableWidget::resizeEvent(event);
emit sizeChanged();
}
最后问题出在哪里:
场景.h
#ifndef SCENE_H
#define SCENE_H
#include <QGraphicsScene>
class Scene : public QGraphicsScene
{
public:
Scene(QObject *parent = nullptr);
protected:
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
void dropEvent(QGraphicsSceneDragDropEvent *event);
};
#endif // SCENE_H
场景.cpp
#include "scene.h"
#include "customtablewidget.h"
#include <QGraphicsSceneDragDropEvent>
#include <QMimeData>
#include <QTableWidget>
#include <QGraphicsProxyWidget>
#include <QVBoxLayout>
#include <QMetaEnum>
#include <QEvent>
#include <QSizeGrip>
Scene::Scene(QObject *parent)
{
setBackgroundBrush(Qt::lightGray);
}
void Scene::dragEnterEvent(QGraphicsSceneDragDropEvent *event) {
if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
event->setAccepted(true);
}
void Scene::dragMoveEvent(QGraphicsSceneDragDropEvent *event) {
if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
event->setAccepted(true);
}
void Scene::dropEvent(QGraphicsSceneDragDropEvent *event) {
QByteArray encoded =
event->mimeData()->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded, QIODevice::ReadOnly);
QStringList rosTables;
QString newString;
while (!stream.atEnd()) {
int row, col;
QMap<int, QVariant> roleDataMap;
stream >> row >> col >> roleDataMap;
rosTables << roleDataMap[Qt::DisplayRole].toString();
}
for (const QString &tableType : rosTables) {
if(tableType == "Images")
{
QPoint initPos(0,0);
CustomTableWidget *wgt = new CustomTableWidget;
QGraphicsRectItem *proxyControl = addRect(initPos.x(), initPos.y(), wgt->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
QSizeGrip * sizeGrip = new QSizeGrip(wgt);
QHBoxLayout *layout = new QHBoxLayout(wgt);
//QGraphicsRectItem *proxyControl = addRect(initPos.x(), initPos.y(), wgt->width(), 20, QPen(Qt::black), QBrush(Qt::darkGreen));
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(sizeGrip, 0, Qt::AlignRight | Qt::AlignBottom);
connect(wgt, &CustomTableWidget::sizeChanged, [wgt, proxyControl](){
proxyControl->setRect(wgt->geometry().adjusted(-10, -10, 10, 10));
});
proxyControl->setPos(initPos.x(), initPos.y());
proxyControl->setFlag(QGraphicsItem::ItemIsMovable, true);
proxyControl->setFlag(QGraphicsItem::ItemIsSelectable, true);
wgt->setColumnCount(2);
wgt->setRowCount(2);
for (int ridx = 0 ; ridx < wgt->rowCount() ; ridx++ )
{
for (int cidx = 0 ; cidx < wgt->columnCount() ; cidx++)
{
QTableWidgetItem* item = new QTableWidgetItem();
item->setText(QString("%1").arg(ridx));
wgt->setItem(ridx,cidx,item);
}
}
QGraphicsProxyWidget * const proxy = addWidget(wgt);
// 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);
}
}
}
我对这个主题进行了广泛的研究,并遇到了另一个非常有用的帖子,因为它让我解决了内部的调整大小问题,QGraphicsView
但它并没有让我解决QGraphicsView
.
我提到的帖子继续对所需的小部件进行子类化并添加一个名为的附加信号sizeChanged();
,这就是我所做的。
我还在声明之前的 AND 之后移动了以下语句QSizeGrip
:
connect(wgt, &CustomTableWidget::sizeChanged, [wgt, proxyControl](){
proxyControl->setRect(wgt->geometry().adjusted(-10, -10, 10, 10));
});
但这并没有引起任何变化,我仍然有这个错误。
感谢您指出解决此问题的正确方向。