2016-04-01 18 views
0

Benim mainthread, arka plan iş parçamı (şebeke hizmeti) çağıran bir Qt penceresi var ve sonuçta yanıtlanması gereken yanıtları bekliyorum.Ana UI iş parçacığındaki lambda/std :: işlevinin çağrılması bir arka plan iş parçacığından çağrılıyor

std::function<void(std::shared_ptr<message>)> delegate_; 

void NetworkService::request(message& msg,std::function<void(std::shared_ptr<message> msg)> fn) 
{ 
    // send the request to the socket and store the callback for later 
    // ... 
    this->delegate_ = fn; 
} 

void NetworkService::onResponseReceived(std::shared_ptr<message> responseMsg) 
{ 
    // is called from the background thread (service) 
    // Here I would like to call the lambda function that the service stored somewhere (currently as an std::func member) 

    // psuedo: call In Main Thread: delegate_(responseMsg); 
} 

Nasıl işliyor: UI şu şekildedir:

// runs in main (GUI) thread 
void QTServer::onButtonClick(){ 
    srv->request(msg, 
     [this] 
      (std::shared_ptr<message> msg){ 
       this->ui.txtResponse->setText("received a response" + msg.data()); 
      }); 
} 

şebeke hizmetidir? Çalışıyor mu?

Sana mainthread bir işlevi çağırmak için QMetaObject::invokeMethod(this, "method", Qt::QueuedConnection kullanabileceğinizi biliyor, bu yüzden aşağıdaki çalıştı:

void NetworkService::onResponseReceived(std::shared_ptr<message> responseMsg) 
{ 
    QMetaObject::invokeMethod(this, "runInMainThread", Qt::QueuedConnection, QGenericArgument(), Q_ARG(std::function<void(std::shared_ptr<message>)>, delegate_)); 
} 

nasıl _delegate için bir argüman olarak burada responseMsg geçmek?

void QTServer::runInMainThread(std::function<void(std::shared_ptr<message>)> f) { 
    f(); 
} 

"Bu argümanlar ile işlev yok" hatası nasıl alınır?

cevap

1

QGenericArgument() 'i kaldır - bu dahili yardımcı sınıftır. ayrıca Q_ARG kullanmak veya veriyi void * olarak göndermek için kendi türlerinizi kaydetmeniz ve sonra geri göndermeniz gerekir.

Q_ARG(void*, delegate_) 

2 soru - STD :: shared_ptr ve f() - - f bir argüman alır fonksiyonudur Çabaladığını ne için tavsiye edilen bir yol inanıyoruz varsayılan argüman

+0

Sonra reinterpret_cast kullanın Q_ART (void *, delegate_) ' – netik

+0

geçişli adresi Q_ARG (void *, & delegate_)' çalışırsanız hmm, bu "hayır yapıcı mevcut" diyor ) *> – jonezq

-1

argüman olmadan çağırır, böylece eklemek QT'ye ulaşmak için QThread ile kombinasyon halinde sinyaller ve yuvalar kullanılır. Örneğin:

MyObject * myObject = new MyObject(); //your worker 
QThread * myThread = new QThread(); //your thread 
myObject->moveToThread(myThread); 

QObject::connect(myThread, SIGNAL(started()), myObject, SLOT(startWorking())); //when thread starts, invoke the working method 
QObject::connect(myObject, SIGNAL(stoppedWorking()), this, SLOT(stoppedWorking())); //when worker signals it finished, invoke slot in main 

QObject::connect(myObject, SIGNAL(stoppedWorking()), myThread, SLOT(quit())); //quit the thread when worker signals that it finished 
QObject::connect(myObject, SIGNAL(gproxyExiting()), gproxy, SLOT(deleteLater())); //cleanup 
QObject::connect(myThread, SIGNAL(finished()), myThread, SLOT(deleteLater())); //cleanup 

Bu şekilde bütün yaşam döngüsü sizin için otomatik olarak yönetilir ve ana iş parçacığı üzerinde işçi ve yuvaların içine sinyaller birbirleriyle iletişim kurmak için her türlü tanımlayabilirsiniz.

İlgili konular