文档说我需要Q_DECLARE_METATYPE一个自定义结构,以便在信号槽中正常工作。
但我尝试过以下代码似乎工作正常吗?
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
struct MyStruct
{
int a;
int b;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
signals:
void test(MyStruct);
public slots:
void tested(MyStruct);
private slots:
void on_pushButton_clicked();
};
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
//------------------------CPP-------------------------------
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(this, SIGNAL(test(MyStruct)),this,SLOT(tested(MyStruct)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::tested(MyStruct t)
{
qDebug()<<t.a<<t.b;
}
void MainWindow::on_pushButton_clicked()
{
MyStruct t;
t.a=1;
t.b=2;
emit test(t);
}
信号插槽没有任何问题,但在下列情况下:
struct SoundType
{
enum Type
{
Bip = 0,
LowBatt,
LowSat,
FarAway,
LostLink
};
};
Q_DECLARE_METATYPE(SoundType::Type)
似乎我必须调用声明才能使用
SoundType ::类型
在信号槽中。
那么在什么情况下我必须使用Q_DECLARE_METATYPE才能使用信号槽?
答案 0 :(得分:4)
何时使用Q_DECLARE_METATYPE?
当该类型与信号/广告位或QVariant
一起使用时,始终使用。
您的测试用例不完整:只要将其中一个连接的对象移动到另一个线程,它就会中断。
您可能还需要qRegisterMetatype<YourType>()
,例如在main
。
答案 1 :(得分:2)
它与信号和插槽没有任何关系。当您希望能够在Q_DECLARE_METATYPE
QVariant
请注意,此宏要求在使用它的位置完全定义类型;对于指针类型,指针也必须完全定义,因此理想情况下,您应该在类声明之后放置宏(再一次,如果要将类型对象存储在QVariant
中,则只需要它)。
答案 2 :(得分:2)
根据我的经验,要在Qt元对象系统中注册自定义枚举,您需要在其范围内使用Q_ENUM
标记枚举,例如:
struct SoundType
{
enum Type
{
Bip = 0,
LowBatt,
LowSat,
FarAway,
LostLink
};
Q_ENUM(Type);
};
这将使我们能够在QML中使用枚举(尽管父类型必须首先在QML中注册)。但在许多情况下,包括Qt本身(例如QAbstractItemModel::data(..., int role)
),使用普通int
代替更方便。
还有其他宏。通常,可以通过在结构的开头键入QObject
来注册不是从Q_GADGET
派生的自定义结构(就像Q_OBJECT
宏一样)。请注意,此类结构必须没有信号或插槽,但它可以像往常一样使用Q_PROPERTY
注册属性(尽管没有通知信号)。
Q_DECLARE_METATYPE
会将基于模板的类型注册到QVariant
中(因此可以使用qvariant_cast<T>()
检索它。)
某些结构需要注册才能使用qRegisterMetaType<T>(name)
在异步信号中排队,例如通过QVector<int>
的信号。