问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Qt + Excel 返回QVariant type=9 无...

发布网友 发布时间:2023-11-06 01:07

我来回答

1个回答

热心网友 时间:2024-07-28 07:42

我使用面struct做说明(管structclass都):
struct Player
{
int number;
QString firstName;
QString lastName;
};
复制代码
QVariant
能QVariant使用自定义数据类型做需要使用Q_DECLARE_METATYPE()向Qt元系统声明自定义类型列所示:
struct Player
{
...
};
Q_DECLARE_METATYPE(Player);
复制代码
作QVariant传递自定义数据类型需要使用QVariant::fromValue()或者qVariantFromValue:
Player player;
object->setProperty("property", QVariant::fromValue(player));
复制代码
更便点自定义类型定义QVariant() 类型转换符:
struct Player
{
...
operator QVariant() const
{
return QVariant::fromValue(*this);
}
};
复制代码
我便像面使用:
Player player;
object->setProperty("property", player);
复制代码
信号槽
于直接连接类型(默认情况直接连接)言使用自定义数据类型做信号参数需要做其其处理像内置数据类型:
connect(sender, SIGNAL(playerCreated(const Player&)), receiver, SLOT(addPlayer(const Player&)));
复制代码
跨线程做编译器给警告:
QObject::connect: Cannot queue arguments of type 'Player'
(Make sure 'Player' is registered using qRegisterMetaType().)
复制代码
我需要先注册Player:
qRegisterMetaType("Player");
qRegisterMetaType( ); (面错误除非名字刚类名)
connect(sender, SIGNAL(playerCreated(const Player&)), receiver, SLOT(addPlayer(const Player&)));
复制代码
QDebug
能:
qDebug() << player;
复制代码

qDebug() << "Player(" << player.number << "," << player.firstName << "," << player.lastName << ")";
复制代码
做呢我需要QDebug<<操作符重载:
inline QDebug operator<<(QDebug debug, const Player& player)
{
debug.nospace() << "Player("
<< player.number << ","
<< player.firstName << ","
<< player.lastName << ")";
return debug.space();
}
复制代码
QDataStream
跟面QDebug像我需要重载<<操作符:
inline QDataStream& operator<<(QDataStream& out, const Player& player)
{
out << player.number;
out << player.firstName;
out << player.lastName;
return out;
}
inline QDataStream& operator>>(QDataStream& in, Player& player)
{
in >> player.number;
in >> player.firstName;
in >> player.lastName;
return in;
}
复制代码
QSettings
QSettings 用QVariant保存键值用QDataStream序列化自定义数据(参考面variantToString函数)
能QSettings使用自定义数据类型需要让Qt元系统知道类型像面介绍QVariant部另外要提供相应QDataStream操作符必须注册流操作符:
qRegisterMetaTypeStreamOperators("Player");
复制代码
处理我像面使用:
QSettings settings;
Player player;
settings.setValue("key", player);
复制代码
QSettings settings;
Player player = value("key").value();
复制代码

参考:
QString QSettingsPrivate::variantToString(const QVariant &v)
{
QString result;
switch (v.type()) {
case QVariant::Invalid:
result = QLatin1String("@Invalid()");
break;
case QVariant::ByteArray: {
QByteArray a = v.toByteArray();
result = QLatin1String("@ByteArray(");
result += QString::fromLatin1(a.constData(), a.size());
result += QLatin1Char(')');
break;
}
case QVariant::String:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Int:
case QVariant::UInt:
case QVariant::Bool:
case QVariant::Double:
case QVariant::KeySequence: {
result = v.toString();
if (result.startsWith(QLatin1Char('@')))
result.prepend(QLatin1Char('@'));
break;
}
#ifndef QT_NO_GEOM_VARIANT
case QVariant::Rect: {
QRect r = qvariant_cast(v);
result += QLatin1String("@Rect(");
result += QString::number(r.x());
result += QLatin1Char(' ');
result += QString::number(r.y());
result += QLatin1Char(' ');
result += QString::number(r.width());
result += QLatin1Char(' ');
result += QString::number(r.height());
result += QLatin1Char(')');
break;
}
case QVariant::Size: {
QSize s = qvariant_cast(v);
result += QLatin1String("@Size(");
result += QString::number(s.width());
result += QLatin1Char(' ');
result += QString::number(s.height());
result += QLatin1Char(')');
break;
}
case QVariant::Point: {
QPoint p = qvariant_cast(v);
result += QLatin1String("@Point(");
result += QString::number(p.x());
result += QLatin1Char(' ');
result += QString::number(p.y());
result += QLatin1Char(')');
break;
}
#endif // !QT_NO_GEOM_VARIANT
default: {
#ifndef QT_NO_DATASTREAM
QByteArray a;
{
QDataStream s(&a, QIODevice::WriteOnly);
s.setVersion(QDataStream::Qt_4_0);
s << v;
}
result = QLatin1String("@Variant(");
result += QString::fromLatin1(a.constData(), a.size());
result += QLatin1Char(')');
#else
Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support");
#endif
break;
}
}
return result;
}

qsetting让保存ini文件能ascii兼容所
我ini文件键值读入 QVariant 需要两步骤:
文件内些字符转义比 "\x1234\t\0"等所需要 unescape
unescape 字符串构造 QVariant
QVariant写入文件:
QVariant 转换字符串
处理字符串特殊字符即 escape

If you store types that QVariant can't convert to QString (e.g., QPoint, QRect, and QSize), Qt uses an @-based syntax to encode the type. For example:
pos = @Point(100 100)
To minimize compatibility issues, any @ that doesn't appear at the first position in the value or that isn't followed by a Qt type (Point, Rect, Size, etc.) is treated as a normal character.
能转化 QString QVariant @-based 编码base(Point, Rect, Size, etc.)
Although backslash is a special character in INI files, most Windows applications don't escape backslashes (\) in file paths:
windir = C:\Windows
QSettings always treats backslash as a special character and provides no API for reading or writing such entries.
反斜杠能用键值
The INI file format has severe restrictions on the syntax of a key. Qt works around this by using % as an escape character in keys. In addition, if you save a top-level setting (a key with no slashes in it, e.g., "someKey"), it will appear in the INI file's "General" section. To avoid overwriting other keys, if you save something using the a key such as "General/someKey", the key will be located in the "%General" section, not in the "General" section.
key用%转义顶层 keyGeneral段General/someKey"%General"段

Following the philosophy that we should be liberal in what we accept and conservative in what we generate, QSettings will accept Latin-1 encoded INI files, but generate pure ASCII files, where non-ASCII values are encoded using standard INI escape sequences. To make the INI files more readable (but potentially less compatible), call setIniCodec().
意思iniasciinon-ASCII全部转移latin-1例外
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? 使用puppeteer实现将htmll转成pdf 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档 【译】将HTML转为PDF的几种实现方案 变形金刚08动画怎么样 执有命者之言,不可不非什么意思 谁能推荐几本小说哦3 奥驰2000驾驶室前盖怎么打开它? 道桥专业专升本能升到哪几个学校?山东省的1 喷油漆的气管,和大货车的吹尘枪管接口一样吗? 在澳留学生被围殴 两次报警求助被拒绝 留学真的安全吗 中国农业大学的经管学院怎么样?148 领天英才保险属于国家认定的保险吗 The book makes me fee| happy.(对画线部分提问)画线的是h 白羊座和天蝎座(男)谈恋爱会幸福吗 告诉我几个魔兽世界 中有用的灰色物品2 稳定却又平凡的感情,天蝎座男生和白羊座女生般配吗,配对指数是多少... 天空有哪些污染物看起来灰白色,对人有哪些危害15 中国农业大学的经济管理学院怎么样1 贸易方式DP是什么意思?22 小腿里打了钢板,小腿中间凹陷下去了是怎么回事 谁给我推荐几本小说!!3 有没有不用格式化硬盘就可以重新分区的软件1 被盗,被冻结了,好友都被拉黑了,我怎么找回?1 领天英才北京劳务派遣公司给北京工作人员上外地保险都是骗人的 英语初学者趣味小游戏2 梦见死去的父亲5 连续几天梦见死去的父亲是怎回事136 低于本科线40分可以补录吗? 做完微针后什么补水面膜都没有用可以吗(&#180;;︵;`)... 微针术后可以敷面膜吗? 我们总是会有一些心里话不敢当面说,怎么办? 怎么看自己的注册多久了注册多久如何查看 协鑫能科最近怎么了?股票协鑫能科后期走势?协鑫能科股票最新消息分红... 所有小鸟出生的时候都有会有绒毛吗 如何在华为C8500上恢复出厂设置的快捷键 九鼎新材的股票可以长期持有吗?九鼎新材业绩下滑原因?九鼎新材属于上证... 道路桥梁专业的专升本可以报湖北工业大学的工程管理吗? 为什么打不开illustrator cs6 安装成功后打开会出现这种提示 PS可以用... 知道地球上ab两点的夹角及距离,如果又知道a点经纬度,如何求b点... 如何往mp4里下电视剧 句容华东仓配中心上班怎么样啊 润锦(深圳)环境科技有限公司怎么样 怎么从西宁到敦煌?218 如何使用家用破壁机?