У меня возникли проблемы с потоковой обработкой Qt, чтобы позволить потоковой части обновлять графический интерфейс моей программы. Похоже, что это известная «проблема» с Qt, поэтому я нашел несколько учебников, но я не понимаю, почему мой пример здесь не работает.QThread с слотами и сигналами, похоже, не создает новый поток
я унаследовал от QThread следующим образом:
class CaptureThread: public QThread {
Q_OBJECT
public:
CaptureThread(const QObject *handler, QPushButton *start) {
CaptureThread::connect(start, SIGNAL(clicked()), this, SLOT(capture_loop()));
CaptureThread::connect(this, SIGNAL(sendPacket(Packet*)),
this, SLOT(receivePacket(Packet*)));
}
signals:
void sendPacket(Packet*);
public slots:
void capture_loop() {
Packet *packet;
while (my_condition) {
packet = Somewhere::getPacket();
//getPacket is define somewhere and is working fine
emit(sendPacket(packet));
std::cout << "Sending packet!" << std::endl;
}
}
};
А вот CaptureHandler:
class CaptureHandler: public QWidget {
Q_OBJECT
public:
CaptureHandler() {
start = new QPushButton("Capture", this);
thread = new CaptureThread(this, start);
thread->start();
}
public slots:
void receivePacket(Packet *packet) {
std::cout << "Packet received!" << std::endl;
/*
Here playing with layout etc...
*/
}
private:
QPushButton *start;
CaptureThread *thread;
};
Я думаю, что сигналы и слоты в порядке, поскольку он отображает на терминале
Sending packet!
Packet received!
Sending packet!
Packet received!
Sending packet!
Packet received!
Но в слоте receivePacket я пытаюсь изменить свой графический интерфейс, и он не работает. GUI просто замерзает, и все, что я могу сделать, это CTRL + C на терминале. Итак, я думаю, что мой capture_loop, который является бесконечным циклом на данный момент, блокирует программу, а это значит, что мой поток не запущен.
Но я назвал thread-> start(). Я даже попытался запустить поток в конструкторе CaptureThread, вызвав this-> start(), но результат тот же.
Любая идея?
Спасибо, что это прекрасно работает. Но я поставил свою петлю внутри метода run, так, как вы сказали, мой поток больше не может получать сигнал. Чтобы остановить мой цикл, я действительно использую thread-> terminate(), это опасно? Я полагаю, что мой метод getPacket может работать над чем-то, убивая поток. – Charrette
Да, это так! Прекращение потока - это необязательная вещь (не каждая система поддерживает ее) и может привести к неопределенному состоянию. Вы должны использовать bool для синхронизации. Создайте функцию, которая устанавливает ее в true/false и проверяет ваш цикл – Felix