2016-10-10 6 views
0

Die Dokumentation sagte, ich muss Q_DECLARE_METATYPE eine benutzerdefinierte Struktur, so dass es richtig in einem Signal-Slot funktioniert.Qt: Wann soll ich Q_DECLARE_METATYPE verwenden?

Aber ich habe den folgenden Code ausprobiert, der scheint gut zu funktionieren?

#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); 
} 

Das Signal Slot funktioniert ohne Probleme, aber im folgenden Fall:

struct SoundType 
{ 
    enum Type 
    { 
     Bip = 0, 
     LowBatt, 
     LowSat, 
     FarAway, 
     LostLink 
    }; 
}; 
Q_DECLARE_METATYPE(SoundType::Type) 

es scheint, dass ich die Erklärung zu nennen haben Inorder

verwenden

SoundType :: Typ

im Signalsteckplatz.

Also, in welchem ​​Fall muss ich Q_DECLARE_METATYPE verwenden, um einen Signalsteckplatz zu verwenden?

+1

Der Dokumentstatus: [* Deklarieren Sie neue Typen mit Q_DECLARE_METATYPE(), um sie für QVariant und andere vorlagenbasierte Funktionen verfügbar zu machen *] (http://doc.qt.io/qt-5/qmetatype.html#details). Ich bin neugierig, wo in den Dokumenten haben Sie gefunden, dass Sie es verwenden müssen, wenn Sie benutzerdefinierte Strukturen in Signalen/Slots verwenden? – thuga

+0

Hier: doc.qt.io/qt-4.8/custom-types.html, oder im Qt5 ist das nicht mehr nötig? Oder ist es nur für anstehende Signale? – Nyaruko

+2

Die Verwendung von benutzerdefinierten Typen in direkten Signal-Slot-Aufrufen ohne 'Q_DECLARE_METATYPE' hat so lange funktioniert, wie ich mich erinnern kann. Ich bin mir nicht sicher, was dieser Teil der Dokumentation versucht zu erzählen. – thuga

Antwort

1

Es hat nichts mit Signalen und Slots zu tun. Q_DECLARE_METATYPE muss verwendet werden, wenn Sie in der Lage sein möchten, Ihren eigenen Typ in einem QVariant

zu speichern. Beachten Sie, dass dieses Makro erfordert, dass der Typ vollständig an dem Punkt definiert ist, an dem er verwendet wird; Für Pointer-Typen muss auch der Pointer vollständig definiert sein, also sollten Sie das Makro idealerweise direkt nach Ihrer Klassendeklaration platzieren (wiederum benötigen Sie es nur, wenn Sie Ihre Typobjekte in einer QVariant speichern wollen).

+0

Bitte lesen Sie meine bearbeiten über den Fall von SoundType :: Typ – Nyaruko

+1

@Nyaruko wickeln, wenn Sie auf Signale und Slots Fehler haben vor Sie haben 'Q_DECLARE_METATYPE' hinzugefügt, dann ist es nur Zufall. Die Verwendung von Aufzählungen in Signalen unterscheidet sich nicht von der Verwendung von Klassen. – SingerOfTheFall

1

Aufgrund meiner Erfahrung, individuelle Aufzählungen in Qt Meta Object System registrieren Sie den Enum mit Q_ENUM in seinem Umfang, zum Beispiel markieren müssten:

struct SoundType 
{ 
    enum Type 
    { 
     Bip = 0, 
     LowBatt, 
     LowSat, 
     FarAway, 
     LostLink 
    }; 
    Q_ENUM(Type); 
}; 

Diese uns ENUM nutzen ermöglichen würde, in QML zum Beispiel (obwohl der Elterntyp zuerst in QML registriert werden müsste). In vielen Fällen, einschließlich in Qt selbst (QAbstractItemModel::data(..., int role) zum Beispiel), ist es jedoch bequemer, einfach int stattdessen zu verwenden.

Es gibt auch andere Makros. Im Allgemeinen kann eine benutzerdefinierte Struktur, die nicht von QObject stammt, durch Eingabe von Q_GADGET am Anfang der Struktur registriert werden (genau wie Q_OBJECT Makro). Beachten Sie, dass eine solche Struktur keine Signale oder Steckplätze haben darf, aber sie kann Eigenschaften wie gewohnt mit Q_PROPERTY registrieren (wenn auch ohne Benachrichtigungssignal).

Q_DECLARE_METATYPE, wie @SingerOfTheFall wies darauf hin, würde Vorlage basiert Typ in QVariant (so kann abgerufen werden unter Verwendung von qvariant_cast<T>()) registrieren.

Einige Strukturen müssen registriert werden, um in asynchronen Signalen unter Verwendung von qRegisterMetaType<T>(name) in die Warteschlange eingereiht zu werden, z. B. ein Signal, das QVector<int> übergibt.

2

Wann soll ich Q_DECLARE_METATYPE verwenden?

Immer wenn der Typ mit entweder Signale/oder Schlitze verwendet QVariant.

Ihr Testfall ist unvollständig: es wird so bald brechen, wie Sie eines der angeschlossenen Objekte zu einem anderen Thread zu bewegen.

können Sie auch auf qRegisterMetatype<YourType>() müssen z in main.

Verwandte Themen