Qt信号槽——传递自定义数据类型

Qt信号槽——传递自定义数据类型

Qt的信号槽机制支持传递int,short,double等C语言的基本类型的变量,也可以传递Qt自己的数据类型。但是在传递用户自己定义的数据类型,或其他数据类型是需要进行注册的。

原因:当一个signal被放到队列(queued)中时,它的参数(arguments)也会被一起放到队列中。这就意味着参数在被传送到slot之前不仅要被拷贝,存储在队列(queue)中。为了能够在队列中存储这些参数(argument),Qt需要去construct、destruct、copy这些对象,而为了让Qt知道怎么去做这些事情,参数的类型需要使用qRegisterMetaType来注册。

参考以下文档: (不得不说Qt的文档是真的好,基本所有问题都可以查看文档解决)

Qt文档:QMetaType Class | Qt Core 5.15.11

原文链接:Qt信号槽机制-传递自定义数据类型(qRegisterMetaType)_宁静致远2021的博客-CSDN博客_qt信号槽传递自定义类型

原文链接:Qt信号槽传递自定义结构体_Liu-Eleven的博客-CSDN博客_qt信号槽传递自定义结构体

1. 方法一

1.1 步骤

  1. 自定义一种类型,在这个类型所在文件包含头文件:#include

  2. 在类型定义完成后,声明自定义类型:Q_DECLARE_METATYPE(Type)

 // This example shows a typical use case of Q_DECLARE_METATYPE():
 struct MyStruct
 {
     int i;
     ...
 };
 ​
 Q_DECLARE_METATYPE(MyStruct)

3.在main()函数中注册自定义类型:template int qRegisterMetaType(const char *typeName);

 // This example registers the class MyClass:
 ​
 qRegisterMetaType("MyClass");

如果还希望使用这种类型的引用,还需要注册:qRegisterMetaType("MyClass&");

此方法可以直接在信号槽中使用自己定义的数据类型。

1.2 例程-传递自定义类

 // 1.包含头文件
 #include      
 //必须包含QMetaType,否则会出现下面错误:     
 //error: expected constructor, destructor, or type conversion before ‘;’ token     
 #include 
 ​
 // 2.自定义类型
 class MyClass
 {
 private:     
     int _count;     
     QString _text;
 public:     
     MyClass();     
     MyClass(int, QString);     
     int count();     
     QString text();       
 };
 ​
 // 3.声明自定义类型
 //在自定义类或者结构体等声明后紧接着用宏Q_DECLARE_METATYPE声明自定义自定义数据类型   
 Q_DECLARE_METATYPE(MyClass)
 
// 4.在main()函数中注册
 int main(int argc, char *argv[])
 {
     qRegisterMetaType("MyClass");
     qRegisterMetaType("MyClass&");
 ​
     QApplication a(argc, argv);
     Form w;
     w.show();
 ​
     return a.exec();
 }

2. 方法二

第二种方法是通过QVariant类型进行转换。

参考文档:QVariant Class | Qt Core 5.15.11

2.1 例程-传递自定义结构体

2.1.1 定义结构体并注册元对象

// 1.定义结构体
 typedef struct student
 {
     int     m_id;
     int     m_age;
     QString m_name;
 } student_t;
 ​
 // 2.注册元对象
 Q_DECLARE_METATYPE(student_t)
     
 class MainWindow : public QMainWindow
 {
     Q_OBJECT
         
 public:
     explicit MainWindow(QWidget *parent = 0);
     ~MainWindow();

 private slots:
     void slot_recvStudent(const QVariant varValue);
     
 signals:
     void signal_sendStudent(const  QVariant varValue);
 }

2.1.2 连接信号槽

connect(this, SIGNAL(slot_recvStudent(const QVariant)), this, SLOT(signal_sendStudent(const  QVariant)));

2.1.3 使用QVariant打包数据并发送

student_t iStudent;
 ​
 iStudent.m_id   = 1;
 iStudent.m_age  = 18;
 iStudent.m_name = "Box";
 ​
 QVariant varValue = QVariant::fromValue(iStudent);
 emit signal_sendStudent(varValue);

2.1.4 在槽函数中解包并打印

void MainWindow::slot_recvStudent(const QVariant varValue)
 {
     if (varVlaue.canConvert())
     {
         student_t student = varValue.value();
         qDebug() << "ID : " << student.m_id;
         qDebug() << "Age : " << student.m_age;
         qDebug() << "Name : " << student.m_name;
     }
 }

你可能感兴趣的:(Qt,qt,开发语言,c++,linux)