Chamar uma função no segmento infantil em Qt?
Pergunta
Eu tenho um thread principal que chama uma função segmento de criança em momentos diferentes, mas eu não tenho certeza se essa é a maneira certa de fazê-lo em Qt.What está errado com o código abaixo e à procura de uma alternativa melhor
Há um fio principal que infinitly sempre quando thread principal libera a criança bloqueio faz um pedaço de trabalho.
#include <QtCore/QCoreApplication>
#include <QSemaphore>
#include <QThread>
QSemaphore sem(0);
class Background : public QThread
{
protected:
void run()
{
for(;;)
{
sem.acquire(1);
qDebug("Child function ran");
}
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Background child;
child.start();
qDebug("Main running");
qDebug("release a lock");
sem.release(1);
qDebug("Do somework in main");
//call child
sem.release(1);
sem.release(1);
return a.exec();
}
Solução
Editar:. retrabalho de todo post para noções básicas de cobertura bem
Background.h
:
#ifndef BACKGROUND_H
#define BACKGROUND_H
#include <QThread>
#include <QObject>
class Background : public QThread
{
Q_OBJECT
public:
Background(QObject* parent = 0):QThread(parent){}
protected:
void run()
{
qDebug(qPrintable(QString("Child function ran in thread: %1").arg(QThread::currentThreadId())));
}
};
class BackgroundConcurrent : public QObject
{
Q_OBJECT
public:
BackgroundConcurrent(QObject* parent = 0):QObject(parent){}
public slots:
void doWork() const
{
qDebug(qPrintable(QString("Concurrent child function ran in thread: %1").arg(QThread::currentThreadId())));
}
};
class BackgroundTrigger : public QObject
{
Q_OBJECT
public:
BackgroundTrigger(QObject* parent = 0):QObject(parent){}
~BackgroundTrigger()
{
foreach(QObject* child, children())
{
QThread* childThread = qobject_cast<QThread*>(child);
if (childThread)
childThread->wait();
}
}
public slots:
void triggerWorker()
{
Background* child = new Background(this);
child->start();
}
};
#endif // BACKGROUND_H
main.cpp
:
#include "Background.h"
#include <QCoreApplication>
#include <QtConcurrentRun>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Using QThread
BackgroundTrigger childTrigger;
qDebug(qPrintable(QString("Main function ran in thread: %1").arg(QThread::currentThreadId())));
// Call child
childTrigger.triggerWorker();
childTrigger.triggerWorker();
// Using QtConcurrent
BackgroundConcurrent cchild;
QFuture<void> future1 = QtConcurrent::run(&cchild, &BackgroundConcurrent::doWork);
QFuture<void> future2 = QtConcurrent::run(&cchild, &BackgroundConcurrent::doWork);
return 0;
}
Exemplo de saída:
Main function ran in thread: 1087038064 Child function ran in thread: 1091267472 Child function ran in thread: 1093417872 Concurrent child function ran in thread: 1095519120 Concurrent child function ran in thread: 1097644944
Certifique-se de executar moc em seus arquivos de cabeçalho, qmake e < a href = "http://www.cmake.org/cmake/help/documentation.html" rel = "nofollow noreferrer"> cmake tanto apoio criar seus makefiles.
Aqui está o arquivo CMakeLists.txt
eu usei para construir o código:
cmake_minimum_required(VERSION 2.6)
#Project name
project(TEST)
#Use Qt4
find_package(Qt4)
if(QT4_FOUND)
set(QT_USE_QTOPENGL TRUE)
include(${QT_USE_FILE})
set(LIBS
${QT_LIBRARIES}
)
#Source files (*.cpp, *.o)
set(TEST_SRCS main.cpp)
#Header files (*.h[pp])
set(TEST_HDRS Background.h)
#Qt macros to handle uic, moc, etc...
QT4_WRAP_CPP(TEST_MOC ${TEST_HDRS} OPTIONS -nw)
set(TEST_ALLSRC ${TEST_SRCS} ${TEST_MOC})
#Create main
add_executable(test ${TEST_ALLSRC})
target_link_libraries(test ${LIBS})
endif(QT4_FOUND)
Outras dicas
Na verdade sua solução atual para o problema é bastante agradável hack.
Se você preferir fazê-lo de uma forma mais "limpa", você deve iniciar um ciclo de eventos em seu segmento de trabalho. Em seguida, o segmento de trabalho será capaz de receber sinais de thread principal. Você poderia chamar uma função no segmento infantil (usando o mecanismo de sinal / slot) do thread principal para a operação do gatilho.
Veja aqui para mais detalhes: http://doc.trolltech.com/4.2/threads. html # per-thread-event-circuito
(Dica: A idéia fundamental é que você cria o objeto receptor no segmento de trabalho; em seguida, seus slots serão processados ??nesse segmento; ou você poderia usar MoveToThread () função)
Parece que você pode querer usar um sinal de que, para se encaixar com o estilo normal de Qt. Confira esta questão ; a resposta aceita não parece corresponder à sua pergunta também.