目录
QVariant的用法 (***)
QVariant 存放指针
QVariant 存取任意类型的指针
QVariant保存指针数据 (**)
----------------------------------------------
测试代码 1:直接调用
测试代码 2:使用模板
----------------------------------------------
问题:
使用指针的麻烦:在代码运行使用之前,必须保证其中的数据有效。。
----------------------------------------------------
要点:
MainWindow *p;
QVariant v_mwPointor = QVariant::fromValue((void *) p); // 存放 + 生成指针
MainWindow* pWmVarInForm = (MainWindow*)v_mwPointor.value<void*>(); // 获取指针
官方手册:
[static] QVariant QVariant::fromStdVariant(const std::variant<Types...> &value)
Returns a QVariant with the type and value of the active variant of value. If the active type is std::monostate a default QVariant is returned.
Note: With this method you do not need to register the variant as a Qt metatype, since the std::variant is resolved before being stored. The component types should be registered however.
This function was introduced in Qt 5.11.
See also fromValue().
[static] QVariant QVariant::fromValue(const T &value)
Returns a QVariant containing a copy of value. Behaves exactly like setValue() otherwise.
Example:MyCustomStruct s;
return QVariant::fromValue(s);Note: If you are working with custom types, you should use the Q_DECLARE_METATYPE() macro to register your custom type.
See also setValue() and value().
T QVariant::value() const
Returns the stored value converted to the template type T. Call canConvert() to find out whether a type can be converted. If the value cannot be converted, a default-constructed value will be returned.
If the type T is supported by QVariant, this function behaves exactly as toString(), toInt() etc.
Example:QVariant v;
MyCustomStruct c;
if (v.canConvert<MyCustomStruct>())
c = v.value<MyCustomStruct>();v = 7;
int i = v.value<int>(); // same as v.toInt()
QString s = v.value<QString>(); // same as v.toString(), s is now "7"
MyCustomStruct c2 = v.value<MyCustomStruct>(); // conversion failed, c2 is emptyIf the QVariant contains a pointer to a type derived from QObject then T may be any QObject type. If the pointer stored in the QVariant can be qobject_cast to T, then that result is returned. Otherwise nullptr is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro.
If the QVariant contains a sequential container and T is QVariantList, the elements of the container will be converted into QVariants and returned as a QVariantList.QList<int> intList = {7, 11, 42};
QVariant variant = QVariant::fromValue(intList);
if (variant.canConvert<QVariantList>()) {
QSequentialIterable iterable = variant.value<QSequentialIterable>();
// Can use foreach:
foreach (const QVariant &v, iterable) {
qDebug() << v;
}
// Can use C++11 range-for:
for (const QVariant &v : iterable) {
qDebug() << v;
}
// Can use iterators:
QSequentialIterable::const_iterator it = iterable.begin();
const QSequentialIterable::const_iterator end = iterable.end();
for ( ; it != end; ++it) {
qDebug() << *it;
}
}See also setValue(), fromValue(), canConvert(), and Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE().
----------------------------------------------------
参考:
QVariant 存取任意类型的指针 、自定义数据类型(****)
https://blog.csdn.net/ken2232/article/details/131733264
开放 Qt窗口的 this指针 的方法汇总 (*****)
https://blog.csdn.net/ken2232/article/details/129634701
----------------------------------------------------
测试代码 1:直接调用
mainwindow.cpp
//QVariant v_mwPointor; //修改为:全局变量。或静态成员?
MainWindow *p;
p =this;
v_mwPointor = QVariant::fromValue((void *) p); //VPtr<MainWindow>::asQVariant(p);
//
qDebug()<<"p =this : 11 : "<<p;
qDebug()<<"v / v_mwPointor : 22 : "<<v_mwPointor;
// ?????
Form *abc =new Form; // pVar在词句之前执行。
abc->show();
form.cpp
//获取
MainWindow* pWmVarInForm=(MainWindow*)v_mwPointor.value<void*>();
qDebug()<<"extern QVariant v_mwPointor : "<<pWmVarInForm;pWmVarInForm->ui->pushButton->setText("abcde");
测试代码 2:使用模板
包含在下面的内容里。
mainwindow.cpp
template <class T> class VPtr
{
public:
static T* asPtr(QVariant v)
{
return (T *) v.value<void *>();
}static QVariant asQVariant(T* ptr)
{
return QVariant::fromValue((void *) ptr);
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
mainwindow.cpp
QVariant v_mwPointor;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
Form *abc =new Form; // pVar在词句之前执行。
abc->show();MainWindow *p;
p =this;
v_mwPointor = VPtr<MainWindow>::asQVariant(p);
qDebug()<<"v / v_mwPointor : "<<v_mwPointor;
}
form.cpp
void Form::on_pushButton_clicked()
{
extern QVariant v_mwPointor;
MainWindow *pWmVarInForm = VPtr<MainWindow>::asPtr(v_mwPointor); //成员函数获取 mW指针
//MainWindow* pWmVarInForm=(MainWindow*)v_mwPointor.value<void*>(); //直接变量获取 mW指针
qDebug()<<"pWmVarInForm : "<<pWmVarInForm;pWmVarInForm->ui->pushButton->setText("abcde");
//p1_mwPointor->close();
}
----------------------------------------
参考:
QVariant 存取任意类型的指针 、自定义数据类型
https://blog.csdn.net/ken2232/article/details/131733264
QVariant类
https://blog.csdn.net/ken2232/article/details/131732801
Qt 子对象引用mainwindow指针的巧妙方法 (***)
https://blog.csdn.net/ken2232/article/details/129638483
Qt里通过传递函数指针实现动态绑定信号/槽 (**)
https://blog.csdn.net/ken2232/article/details/131566404
----------------------------------------------------
QVariant 存取任意类型的指针
QVariant v = QVariant::FromValue((void *) yourPointerHere);
yourPointer = (YourClass *) v.value<void *>();
官方手册:
[static] QVariant QVariant::fromValue(const T &value)
Returns a QVariant containing a copy of value. Behaves exactly like setValue() otherwise.
Example:
MyCustomStruct s;
return QVariant::fromValue(s);
Note: If you are working with custom types, you should use the Q_DECLARE_METATYPE() macro to register your custom type.
See also setValue() and value().
示例:存放指针
(已验证****)
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// need 1: 声明为全局变量:QVariant pVar;
//保存
pVar=QVariant::fromValue((void*)this);
qDebug()<<"pVar in MainWindow : "<<pVar;
Form *abc =new Form; // pVar在此句之前执行。
abc->show();
}
form.cpp
extern QVariant pVar;
void Form::on_pushButton_clicked()
{
// need 1: #include "ui_mainwindow.h"
// need 2: extern QVariant pVar;
//获取
MainWindow* pVarInForm=(MainWindow*)pVar.value<void*>();
qDebug()<<"extern var : "<<pVarInForm;
pVarInForm->ui->pushButton->setText("abcde"); //MainWindow需要开放 ui指针
//pVarInForm->close();
}
==============================
采用 QVariant来存放指针,似乎使用也来越广泛、越来越重要了?
在 Qt 6.0之后,就有了一个专门的来来处理
QVariantPointer Class
https://doc.qt.io/qt-6/qvariantpointer.html
QVariantPointer Class
template <typename Pointer> class QVariantPointer
QVariantPointer is a template class that emulates a pointer to QVariant based on a pointer. More...
Header: | #include <QVariantPointer> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
Since: | Qt 6.0 |
Public Functions
QVariantPointer(const Pointer *pointer) | |
QVariantRef<Pointer> | operator*() const |
Pointer | operator->() const |
Detailed Description
QVariantConstPointer wraps a pointer and returns QVariantRef to it from its operator*(). This makes it suitable as replacement for an actual pointer. We cannot return an actual pointer from generic iterators as the iterators don't hold an actual QVariant.
Member Function Documentation
[explicit]
QVariantPointer::QVariantPointer(const Pointer *pointer)
Constructs a QVariantPointer from the given pointer.
QVariantRef<Pointer> QVariantPointer::operator*() const
Dereferences the QVariantPointer to a QVariantRef.
Pointer QVariantPointer::operator->() const
Dereferences and returns the pointer. The pointer is expected to also implement operator->().
==============================
QVariant的用法 (***)
https://blog.csdn.net/xiaopei_yan/article/details/81410092
前言
QVariant这个类很神奇,或者说方便。很多时候,需要几种不同的数据类型需要传递,如果用结构体,又不大方便,容器保存的也只是一种数据类型,而QVariant则可以统统搞定。
介绍
帮助文档上说:The QVariant class acts like a union for the most common Qt data types.。
QVariant 这个类型充当着最常见的数据类型的联合。QVariant 可以保存很多Qt的数据类型,包括QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、 QPalette、QPen、QPixmap、QPoint、QRect、QRegion、QSize和QString,并且还有C++基本类型,如 int、float等。
当然,如果支持的类型没有想要的,没关系,QVariant也可以支持自定义的数据类型。被QVariant存储的数据类型需要有一个默认的构造函数和一个拷贝构造函数。为了实现这个功能,首先必须使用Q_DECLARE_METATYPE()宏。通常会将这个宏放在类的声明所在头文件的下面:
Q_DECLARE_METATYPE(MyClass)
示例
(1)支持的类型。对于QVariant支持的类型,可直接赋值,但是取值时,对于存入的是什么类型,取出也要为这个类型。
QVariant var;
var.setValue(12);
int data=var.toInt();
或
QVariant var=12;
int data=var.toInt();
(2)对于不支持的类型,如自己定义的结构体。由于Qt都是基于元对象系统,故要在头文件里面要注册此类属于元类型。存储用到了QVariant QVariant::fromValue(const T &value) 或 void QVariant::setValue(const T &value)。获取用到了
T QVariant::value() const,在这之前一般要bool QVariant::canConvert(int targetTypeId) const先用进行判断,是否可以转换。例子如下:
.h文件声明
struct MyClass{
int id;
QString name;
};
Q_DECLARE_METATYPE(MyClass)
.cpp文件定义
//存储数据
MyClass myClass;
myClass.id=0;
myClass.name=QString("LiMing");
data[0]=QString("ddd");
data[1]=123;
data[3]=QVariant::fromValue(myClass);
//获取数据
QString str=data.value(0).toString();
int val=data.value(1).toInt();
if(data[3].canConvert<MyClass>())
{
MyClass myClass=data[3].value<MyClass>();
int id=myClass.id;
QString name=myClass.name;
}
(3)对于不支持的C++基础数据类型,如 short char,先通过toInt()转化为int类型,然后再将int转为其原本的数据类型。
//-------------------------------char--------------------------
//char -> QVariant
QVariant var='B';
qDebug()<<var; //QVariant(int, 66)
// QVariant ->char
char channel=var.toInt();
//------------------------------short--------------------------
//short -> QVariant
short dataType=12;
QVariant var2=dataType;
qDebug()<<var2; //QVariant(int, 12)
//QVariant -> short
short temp=(short)var2.toInt();
(4)保存指针,感觉这个比较强大,也比较容易用到。如
//保存
QVariant var=QVariant::fromValue((void*)event);
//获取
QPaintEvent* e=(QPaintEvent*)var.value<void*>();
(5)还有种写法,用QVariant的构造函数QVariant(int typeId, const void *copy)。
虽然不常用,特别是指针类型,即
QMetaType::VoidStar, 和 QMetaType::QObjectStar,
一般还是用fromValue。但是还是以存取QObject*为例补充下吧,
起码知道写法。
QObject* obj=new QObject;
obj->setObjectName("myObj");
//保存
QVariant var=QVariant(QMetaType::QObjectStar,&obj);
//提取
QObject* myobj=qvariant_cast<QObject*>(var);
if(myobj!=NULL)
qDebug()<<myobj->objectName();
obj->deleteLater();
(6) QVariant与json之间的各种转换
QVariant与Json的各种纠葛——Qt_十年之少的博客-CSDN博客
警告:
不要盲目的随便使用QVariant之类,它比较消耗内存和影响处理速度!!!
结束语
程序中有很多小点,存储着很大的智慧,就如QVariant就是如此。
————————————————
版权声明:本文为CSDN博主「十年之少」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaopei_yan/article/details/81410092
==============================
QVariant保存指针数据 (***)
https://www.cnblogs.com/alleyonline/p/4781304.html
QVariant 默认无法保存指针数据,因为以 void *为参数的QVariant构造函数是私有的。
但通过QT提供的Meta Type机制,可以将任意指针存放到QVariant中。
需要使用Q_DECLARE_METATYPE宏注册类型。
Q_DECLARE_METATYPE(QStandardItemModel*)
之后,就可以使用QVariant::fromValue存放数据,使用QVariant::value获取数据了。
return QVariant::fromValue(model_);
//....
QStandardItemModel* model = some_value.value();
使用QVariant和标识项目中数据类型的Qt::ItemDataRole,可以方便地将任意数据存放进QT提供的预定义模型中。
比如,在同一个QStandardItem中使用不同的Role,存放多个数据。
自定义的数据角色
enum CustomItemRole
{
LevelModelRole = Qt::UserRole + 1000,
TimeModelRole = Qt::UserRole + 1010,
FileModelRole = Qt::UserRole + 1020
};
存放特定角色的数据
type_of_level_item->setData(QVariant::fromValue(level_list_model),LevelModelRole);
获取特定角色的数据
QVariant data = item->data(Qt::LevelModelRole);
因为QStandardItemModel以行为单位建立树形结构,所以要实现更复杂的树形结构,可以使用自定义的DataRole来存储数据。
==================================
QVariant 存放指针
QVariant v = QVariant::fromValue((void *) yourPointerHere);
yourPointer = (YourClass *) v.value<void *>();
--------------------------------------------------------------------------------------------------
You can store many types of data into QVariant, like int, string, etc. Also you can store pointers, but only pointers to void (void ). But what happens when you want to set a property of a object to a instance of class, with setProperty, and after that, you want to retrieve that property? QVariant accepts void , so you can do something like the following, to store it into QVariant:
QVariant v = QVariat::FromValue((void *) yourPointerHere);
and then something like this, in order to retrieve it back from QVariant://你也可以恢复到指针
yourPointer = (YourClass *) v.value<void *>();
Having this done each time you have to get the property or set the property is a bit tendentious. We can make this more friendly, using templates:
template <class T> class VPtr { public: static T* asPtr(QVariant v) { return (T *) v.value<void *>(); } static QVariant asQVariant(T* ptr) { return QVariant::fromValue((void *) ptr); } };
So how do you use this?
Assuming you have a class MyClass, and you want to store a pointer to this class as a property of a QWidget, or any QObject, or you want to convert it to QVariant,
you can do the following:
MyClass *p;
QVariant v = VPtr<MyClass>::asQVariant(p);
MyClass *p1 = VPtr<MyClass>::asPtr(v);
I think this is more developer friendly than having to write each time those conversion code sequences.
转载:http://ju.outofmemory.cn/entry/179497