Qt 使用setUserData和userData要注意的问题

在学习Qt的过程中,给界面中存储一些有用的数据,这些数据对于用户来说都是至关重要的,它们在交互过程中大部分都会被用到,例如:单击一个Ui控件,可以获取绑定在控件上的数据。
例子如下
第一步:首先定义需要放在Ui控件中的结构体

struct DHStruct:QObjectUserData
{
    DHStruct()
    {
        index = 0;
        info = nullptr;
        size = QSize(0,0);
        pt = QPoint(0,0);
    }
    int index;
    QString info;
    QSize size;
    QPoint pt;

};
Q_DECLARE_METATYPE(DHStruct)

注意,这里使用派生自QObjectUserData类型,是为了后面能使用QObjectUserData类里的setUserData()和userData()这两个函数。如果不使用这两个接口,则不需要定义为QObjectUserData。
绝大部分存储用户数据的接口都使用的是QVariant,也就是我们常说的“万能变量”。对于自定义数据类型,如果要使用QVariant,就必须使用Q_DECLARE_METATYPE注册。通过添加Q_DECLARE_METATYPE()这个宏让QOject及其子类知道这个类型。

这里要注意的是如果要在队列信号使用或者用用槽连接,要先调用这个函数qRegisterMetaType()
【这里是在运行的时候,对他进行注册】

第二步:组装数据,放到Ui控件中

    ui->setupUi(this);
    QList<DHStruct> list;
    m_pCb = new QComboBox(this);
    m_pCb->addItem(tr("FlatCap"),Qt::FlatCap);
    m_pCb->addItem(tr("SquareCap"),Qt::SquareCap);
    m_pCb->addItem(tr("RoundCap"),Qt::RoundCap);
    m_pCb->addItem(tr("MPenCapStyle"),Qt::MPenCapStyle);
    connect(m_pCb,SIGNAL(activated(int)),this,SLOT(ShowPenStyle(int)));

    DHStruct dh1;
    dh1.pt = QPoint(0,0);
    dh1.size = QSize(10,10);
    dh1.index =2;
    dh1.info = "DHL";
    m_pCb->setUserData(Qt::UserRole,&dh1);//第一种传递:把定义的结构体取地址放进去
    list.append(dh1);

    m_pBrushCb = new QComboBox(this);
    m_pBrushCb->setGeometry(0,50,200,20);
    //m_pBrushCb->addItem(tr("SolidPattern"),static_cast<int>(Qt::SolidPattern));

    DHStruct* dh2 = new DHStruct;
    dh2->pt = m_pBrushCb->pos();
    dh2->size = m_pBrushCb->size();
    dh2->index = 8;
    dh2->info = "达州";
    m_pBrushCb->setUserData(Qt::UserRole,dh2);//第二种传递:把申明的结构体指针对象传递进去
    list.append(*dh2);

第三步:从Ui控件获取刚才放进去的自定义结构体类型

void Widget::ShowPenStyle(int style)
{
   Qt::PenCapStyle value = Qt::PenCapStyle(m_pCb->itemData(m_pCb->currentIndex(),Qt::UserRole).toInt());
   DHStruct* data =  (DHStruct*)m_pCb->userData(Qt::UserRole);//会发现这个data里面数据有乱码

   int j = 0;
}

void Widget::ShowBrushStyle(int value)
{
    Qt::BrushStyle style = Qt::BrushStyle(m_pBrushCb->itemData(value,Qt::UserRole).toInt());
    DHStruct* data =  (DHStruct*)m_pBrushCb->userData(Qt::UserRole);//能正确解析出放在控件里的自定义结构体
    int j = 0;
}

总结:一定要定义结构体指针类型,setUserData,然后从userData获取的数据才是有效的!

附图,有图有真相
Qt 使用setUserData和userData要注意的问题组装数据

Qt 使用setUserData和userData要注意的问题
获取数据

最后附上不错两个博客文章
1.Qt文档阅读笔记-关于Q_DECLARE_METATYPE原理以及使用
https://it1995.blog.csdn.net/article/details/82084295

2.qt setData()和data()
https://blog.csdn.net/swartz_lubel/article/details/55195509

上一篇:解密RimWorld环世界地形数据


下一篇:手把手教你用MATLAB制作一款 [狗头翻牌子] 小游戏(点灯游戏)