【发布时间】:2021-01-28 03:59:39
【问题描述】:
我有一个小例子.ui,用户可以使用QGraphicsProxyWidget 将一个特定的小部件(在我的例子中是QTableWidget)从QListWidget 拖放到QGraphicsView,如下所示。
基本上我一直在寻找的行为是:
如果我拖放“Imgaes”,QTableWidget 上的 QGraphicsView 将有 2 列和 2 行; (哪个是对的)
如果我拖放“路径”而不是QGraphicsView 上的QTableWidget 将有 3 列和 3 行; (这是错误的)
在“路径”的选择下方,仍然给出 2 行 2 列而不是 3 行 3 列
代码下方:
scene.h
class Scene : public QGraphicsScene {
enum LaserTableWidget {
Images,
Path
};
Q_ENUM(LaserTableWidget)
public:
Scene(QObject *parent = nullptr);
void compare(const QString& comp);
template<typename QEnum>
std::string QtEnumToString (const QEnum value)
{
return std::string(QMetaEnum::fromType<QEnum>().valueToKey(value));
}
protected:
void dropEvent(QGraphicsSceneDragDropEvent *event);
scene.cpp
Scene::Scene(QObject *parent) : QGraphicsScene(parent) {
setBackgroundBrush(Qt::lightGray);
}
void Scene::compare(const QString &comp)
{
// get information about the enum named "LaserTableWidget"
QMetaObject MetaObject = this->staticMetaObject;
QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator("LaserTableWidget"));
QStringList tabs;
switch (MetaEnum.keyToValue(comp.toUpper().toLatin1()))
// or simply switch (MetaEnum.keyToValue(word)) if no string modification is needed
{
case Images:
for (const QString &color : tabs) {
QPoint initPos(0,0);
QTableWidget *wgt = new QTableWidget;
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
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);
}
break;
case Path:
for (const QString &color : tabs) {
QPoint initPos(0,0);
QTableWidget *wgt = new QTableWidget;
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
proxyControl->setFlag(QGraphicsItem::ItemIsMovable, true);
proxyControl->setFlag(QGraphicsItem::ItemIsSelectable, true);
wgt->setColumnCount(3);
wgt->setRowCount(3);
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);
}
break;
default:
break;
}
}
void Scene::dropEvent(QGraphicsSceneDragDropEvent *event) {
QByteArray encoded =
event->mimeData()->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded, QIODevice::ReadOnly);
QStringList rosTables;
while (!stream.atEnd()) {
int row, col;
QMap<int, QVariant> roleDataMap;
stream >> row >> col >> roleDataMap;
rosTables << roleDataMap[Qt::DisplayRole].toString();
}
compare(const QString &comp)
}
我尝试使用在头文件中声明的template 函数,为了完整起见,我还在下面附上了:
template<typename QEnum>
std::string QtEnumToString (const QEnum value)
{
return std::string(QMetaEnum::fromType<QEnum>().valueToKey(value));
}
也许我的模板函数是错误的选择?如果可能的话,我试图找到一种使用它的方法。
这就是为什么我切换到 void compare(const QString& comp); 函数并尝试将工作委托给 switch - case 语句的原因,但这也没有像我预期的那样工作,我仍然看到相同的 QtableWidget 掉到QGraphicsView.
当然,我做了更多的研究,发现了this 来源,最重要的是this post,这对于理解基本比较很有用,在这篇文章之后,我决定继续尝试应用Q_ENUM - QString 甚至QStringList 作为一个有价值的工具。但我无法弄清楚我做错了什么。
谁能说明哪种方法更好? (或者也许他们都是正确的)并尝试解释我缺少什么来解决这个问题。
【问题讨论】:
-
我认为给定的代码甚至不会产生错误的输出。
tabs只是一个空列表,那么对于tabs中的每个元素,显示一个表格? -
我假设
comp是“图像”或“路径”,为什么使用toUpper()? -
您好@NgocMinhNguyen,感谢您停下来阅读这个问题。是的
comp用于“图像”或“路径”。我遇到的问题是我试图将其与使用template<typename QEnum>函数结合起来。与QEnum和QString相比,这是我练习使用template<>的一种方式,但是缺少一些东西,无法弄清楚可能是什么。 -
你还没有回答我的问题
-
对不起,你是对的 :) 好的,所以:1) 是的,
tabs中的每个元素都会显示一个表格。 2) 我使用toUpper()的方式使从QListWidget选择(例如“图像”、“路径”)到QGraphicsView的darg-drop 区分大小写。因此,如果有“图像”而不是“图像”,MetaEnum应该抛出错误,因此template<typename QEnum>应该能够处理。
标签: c++11 qt5 qtablewidget qstring qenum