2016-10-10 7 views
0

설명서에 따르면 신호 구조에서 제대로 작동 할 수 있도록 사용자 지정 구조를 Q_DECLARE_METATYPE해야합니다.Qt : 언제 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 :: 유형을 사용하는 inorder를 선언 전화를해야 할 것 같습니다

신호 슬롯.

어떤 경우 신호 슬롯을 사용하려면 Q_DECLARE_METATYPE을 사용해야합니까?

+1

docs 상태 : [* Q_DECLARE_METATYPE()로 새로운 유형을 선언하여 QVariant 및 기타 템플릿 기반 기능 *] (http://doc.qt.io/qt-5/qmetatype.html#details)에서 사용할 수 있도록합니다.). 내가 궁금한 점은 신호/슬롯에서 맞춤 구조를 사용할 때 문서를 사용해야한다는 점 이었습니까? – thuga

+0

여기 : doc.qt.io/qt-4.8/custom-types.html 또는 Qt5에서 더 이상이 작업을 수행 할 필요가 없습니다. 아니면 그냥 대기열에 신호입니까? – Nyaruko

+2

Q_DECLARE_METATYPE없이 직접 신호 슬롯 호출에서 사용자 정의 유형을 사용하는 것은 내가 기억할 수있는 한 계속 작동했습니다. 나는 문서의 그 부분이 무엇을 말하려고하는지 잘 모르겠습니다. – thuga

답변

1

신호와 슬롯에는 아무런 관련이 없습니다. 은 자신의 형식을 저장할 수 있기를 원할 때 사용해야합니다. QVariant

이 매크로는 형식이 사용되는 지점에서 완전히 정의되어야합니다. 포인터 유형에 대해서도 포인터를 완전히 정의해야하므로 이상적으로 클래스 선언 바로 뒤에 매크로를 두어야합니다 (유형 객체를 QVariant에 저장하려는 경우에만 필요합니다).

예를 들어, 당신은 그 범위 내에서 Q_ENUM를 사용하여 열거를 표시해야 Qt는 메타 개체 시스템에서 사용자 정의 열거를 등록하는 내 경험을 바탕으로
+0

SoundType :: Type의 경우 편집을 참조하십시오. – Nyaruko

+1

@Nyaruko, 이전에 신호 및 슬롯에 오류가있는 경우 'Q_DECLARE_METATYPE'을 추가했다면 우연 일뿐입니다. 신호에서 열거 형을 사용하는 것은 클래스를 사용하는 것과 다르지 않습니다. – SingerOfTheFall

1

: 이것은에 열거를 사용 할 수있게 할

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_PROPERTY을 사용하여 속성을 등록 할 수 있습니다.

Q_DECLARE_METATYPE @SingerOfTheFall이 지적한대로 템플릿 기반 유형을 QVariant에 등록합니다 (따라서 qvariant_cast<T>()을 사용하여 검색 할 수 있습니다).

qRegisterMetaType<T>(name)을 사용하여 비동기 신호에 큐에 넣기 위해 등록해야하는 구조 (예 : QVector<int>을 전달하는 신호).

2

언제 Q_DECLARE_METATYPE을 사용해야합니까?

항상 신호 타입/또는 슬롯 QVariant 함께 사용할 때.

테스트 케이스가 불완전합니다. 연결된 객체 중 하나를 다른 스레드로 이동하자마자 중단됩니다.

qRegisterMetatype<YourType>() 등이 필요할 수도 있습니다. main에 있습니다.

관련 문제