2015-12-03 70 views
0

類型的參數我有問題。我有一個自定義類BasicSpace。這個類不是qobject(沒有宏),也沒有被qobject繼承。這是簡單的類有一些數據,QTIME等 我:QVector <自定義類>連接線程無法排隊

connect(connector,SIGNAL(finishedReadData(QVector<BasicSpace>&)),&window,SLOT(updateData(QVector<BasicSpace>&))); 

我嘗試

qRegisterMetaType< QVector<BasicSpace> >("QVector<BasicSpace>"); 
main.cpp

但Qt的還是當槽被稱爲帶我味精:

的QObject ::連接:無法排隊類型 'QVector &' 的參數(確保 'QVector &' 使用qRegisterMetaType()註冊。 )

我的濃度介乎線程。

我的項目是先進的,所以我儘量避免typedef解決方案不同的名字,所以我不測試它。 有人可以幫助我嗎?

編輯 THX弗蘭克。我替換QVector這樣的參考,沒有&。這項工作,但我有疑問。它的作品,但線程連接總是複製數據,所以沒有參考數據prabodly是複製,第一次在功能和第二次之間線程複製?

我解決了50%的問題。我有工作代碼,但主要問題 - 排隊連接中的模板類型參考值未解決。

+0

不通過非const參考,但無論是常量引用或值。即'finishedReadData'(QVector )'。 –

+0

弗蘭克是對的。儘管如此,它適用於我沒有像你嘗試它的問題。不需要註冊任何東西。您能否請您發佈您的插槽和信號聲明。通常不需要考慮信號和時隙參數,並且在大多數情況下不需要註冊該類型。 – Aaron

回答

0

當您連接的信號,並且住在同一個線程對象的插槽,使用Qt::DirectConnection類型。在這種情況下,插槽將作爲正常的函數調用執行。您不必通過qRegisterMetaType註冊數據類型,並且當您將數據作爲參考發送時,它不會被複制。

當發送者和接收者對象不住在同一個線程,使用Qt::QueuedConnection類型。現在,當您發送一些數據時,它將被複制到事件隊列中,而不管您是通過值還是通過引用來發送它。您的數據類型也必須使用qRegisterMetaType註冊。

下面是一個簡單的例子示出這種行爲:

class MyObject 
{ 
public: 
    MyObject() 
    { 
     qDebug() << Q_FUNC_INFO; 
    } 

    MyObject(const MyObject &other) 
    { 
     qDebug() << Q_FUNC_INFO; 
    } 

    ~MyObject() 
    { 
     qDebug() << Q_FUNC_INFO; 
    } 

}; 

class Widget : public QWidget 
{ 
    Q_OBJECT 

public: 
    Widget(QWidget *parent = 0); 
    ~Widget(); 

signals: 
    void myObjectSignal1(const MyObject &obj); 
    void myObjectSignal2(const MyObject &obj); 

public slots: 
    void testDirectConnection(); 
    void testQueuedConnection(); 

    void myObjectSlot(const MyObject &obj); 

}; 

Widget::Widget(QWidget *parent) 
    : QWidget(parent) 
{ 
    QHBoxLayout *layout = new QHBoxLayout(this); 

    QPushButton *b1 = new QPushButton; 
    b1->setText("direct"); 
    layout->addWidget(b1); 
    connect(b1, SIGNAL(clicked()), this, SLOT(testDirectConnection())); 

    QPushButton *b2 = new QPushButton; 
    b2->setText("queued"); 
    layout->addWidget(b2); 
    connect(b2, SIGNAL(clicked()), this, SLOT(testQueuedConnection())); 

    qRegisterMetaType<MyObject>("MyObject"); 

    connect(this, SIGNAL(myObjectSignal1(MyObject)), 
      this, SLOT(myObjectSlot(MyObject))); 
    connect(this, SIGNAL(myObjectSignal2(MyObject)), 
      this, SLOT(myObjectSlot(MyObject)), Qt::QueuedConnection); 
} 

Widget::~Widget() 
{ 

} 

void Widget::testDirectConnection() 
{ 
    MyObject obj; 
    emit myObjectSignal1(obj); 
} 

void Widget::testQueuedConnection() 
{ 
    MyObject obj; 
    emit myObjectSignal2(obj); 
} 

void Widget::myObjectSlot(const MyObject &obj) 
{ 
} 

Qt::DirectConnection情形:

  1. myObjectSignal1信號使用 Qt::DirectConnection連接到myObjectSlot

  2. MyObject在裏面Widget::testDirectConnection創建。

  3. myObjectSignal1信號觸發器myObjectSlot作爲正常的函數調用。

  4. MyObject通過引用傳遞給myObjectSlot
  5. myObjectSlot執行結束。
  6. MyObject隨着對照離開Widget::testDirectConnection而被銷燬。

的輸出將是:

MyObject::MyObject() 
MyObject::~MyObject() 

Qt::QueuedConnection情形:

  1. myObjectSignal2信號使用 Qt::QueuedConnection連接到myObjectSlot
  2. MyObjectWidget::testQueuedConnection內部創建。

  3. myObjectSignal2信號觸發器和MyObject被複制到事件隊列中。

  4. MyObject隨着控制離開Widget::testQueuedConnection而被銷燬。
  5. 控制權返回到事件循環並執行myObjectSlot,獲得MyObject的副本。
  6. MyObject的副本隨着控件離開myObjectSlot而被銷燬。

的輸出將是:

MyObject::MyObject() // object is created inside testQueuedConnection 
MyObject::MyObject(const MyObject&) // object is copied 
MyObject::~MyObject() // object is destroyed 
MyObject::~MyObject() // copy is destroyed 

如果要避免額外的對象副本,則可以對您數據使用new操作者堆中分配存儲器中,然後通過一個指針。但在這種情況下,您必須確保在處理結束後您的對象被銷燬。

上參數Qt中的信號槽連接複製良好的文章:http://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/

相關問題