如何解决如何正确比较Q_ENUM和QStringList
我有一个小示例.ui
,其中用户可以使用QListWidget
特定的小部件从QGraphicsView
拖放到QGraphicsProxyWidget
(在我的情况下是{ {1}}),如下所示。
我一直在寻找的行为是:
如果我拖放“ Imgaes”,则QTableWidget
上的QTableWidget
将具有2列和2行; (哪个是正确的)
如果将“路径”拖放到QGraphicsView
上的QTableWidget
处,将有3列和3行; (这是错误的)
在“路径”(Path)的选择下面,它仍然提供2行2列而不是3行3列
代码下方:
scene.h
QGraphicsView
scene.cpp
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::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,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,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);
语句的原因,但是它也无法按我预期的那样工作,并且我仍然看到完全相同的{{ 1}}放在switch - case
上。
当然,我做了更多的研究,发现了this的源代码,尤其是this post,这对理解基本比较很有帮助,在这篇文章之后,我决定继续尝试使用{{ 1}}甚至是QtableWidget
作为有价值的工具。但是我不知道自己在做什么错。
任何人都可以阐明哪种方法更好吗? (或者也许它们都是正确的),并尝试解释我缺少的解决此问题的方法。
解决方法
我在您的代码中看到两个问题:
-
错误的参数传递给
keyToValue()
。由于您的枚举中包含Image
和Path
,因此要传递给keyToValue()
的有效值为“ Image”(返回0)和“ Path”(返回1),其他值将返回-1。 -
在函数
Scene::compare()
中,tabs
只是作为一个空的QStringList
创建的,因此循环for (const QString &color : tabs)
中的代码永远不会执行
下面是一个测试程序,向您展示我的意思:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMetaEnum>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
enum LaserTableWidget
{
Images,Path
};
Q_ENUM(LaserTableWidget)
template<typename enum_type>
QString QtEnumToString (const enum_type value)
{
return QMetaEnum::fromType<enum_type>().valueToKey(value);
}
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QDebug>
#include <QStringList>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// First problem: wrong parameter passed to keyToValue()
qDebug() << 1 << QtEnumToString<LaserTableWidget>(Images);
qDebug() << 2 << QtEnumToString<LaserTableWidget>(Path);
QMetaObject MetaObject = this->staticMetaObject;
QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator("LaserTableWidget"));
qDebug() << 3 << MetaEnum.keyToValue(QtEnumToString<LaserTableWidget>(Path).toUpper().toLatin1());
qDebug() << 4 << MetaEnum.keyToValue(QtEnumToString<LaserTableWidget>(Path).toStdString().c_str());
switch (MetaEnum.keyToValue(QtEnumToString<LaserTableWidget>(Path).toUpper().toLatin1()))
{
case Images:
qDebug() << "switch Images";
break;
case Path:
qDebug() << "switch Path";
break;
default:
qDebug() << "switch default";
break;
}
// Second problem: tabs is empty
QStringList tabs;
for (const QString &color : tabs)
qDebug() << color; // this line is never executed
}
MainWindow::~MainWindow()
{
}
输出:
1 "Images"
2 "Path"
3 -1
4 1
switch default
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。