Qt: Слот для сигналов не работает

Я пытаюсь реализовать систему сигналов и слотов между основным графическим интерфейсом и другим объектом, перемещенным в другой поток … следующее — как выглядит дизайн класса … к сожалению, не могу его реализовать …

mainwindow.h

signals:
void StopDisplayWidget();
void StartDisplayWidget();
void signalFromGUI();

private slots:
void on_pushButton_start_display_clicked();

void on_pushButton_stop_display_clicked();

void on_pushButton_check_clicked();

private:
Ui::MainWindow *ui;
displaythread *threadforDisplay;
display *displayWidget;
QThread *WorkerDisplay;

mainwindow.cpp

{
threadforDisplay = new displaythread;
threadforDisplay->setptr2display(displayWidget);

WorkerDisplay = new QThread;
QObject::connect(WorkerDisplay,SIGNAL(started()),threadforDisplay,SLOT(Process()));

QObject::connect(this,SIGNAL(StartDisplayWidget()),threadforDisplay,SLOT(StartDisplay()));
QObject::connect(this,SIGNAL(StopDisplayWidget()),threadforDisplay,SLOT(StopDisplay()));
QObject::connect(this,SIGNAL(signalFromGUI()),threadforDisplay,SLOT(Check()));

threadforDisplay->moveToThread(WorkerDisplay);
}

void MainWindow::on_pushButton_start_display_clicked()
{
if(!threadforDisplay->IsDisplayActive())
emit this->StartDisplayWidget();

if(!WorkerDisplay->isRunning())
WorkerDisplay->start();
}

void MainWindow::on_pushButton_stop_display_clicked()
{
if(threadforDisplay->IsDisplayActive())
{
emit this->StopDisplayWidget();
}
}

void MainWindow::on_pushButton_check_clicked()
{
std::cout<<"CHECKING SIGNAL SLOT"<<std::endl;
emit this->signalFromGUI();
}

threadforDisplay это указатель на класс отображения темы который выглядит как

displaythread.h

#include <QObject>
#include <QWaitCondition>
#include <QMutex>
#include "display.h"
class displaythread : public QObject
{
Q_OBJECT
public:
explicit displaythread(QObject *parent = 0);
bool IsDisplayActive() const;
void setptr2display(display *);

signals:

public slots:
void Process();
void StartDisplay();
void StopDisplay();
void Check();private:
void SleepThread();

volatile bool stopped,running;
QMutex mutex;
QWaitCondition waitcondition;
display *displayinGUI;

displaythread.cpp

void displaythread::setptr2display(display *ptr)
{
displayinGUI = ptr;
}

void displaythread::Process()
{
std::cout<<"RECEIVED START PROCESS SIGNAL"<<std::endl;
running = true;
while(true)
{
if(!stopped)
{
displayinGUI->update();
this->SleepThread();
}
}

}

void displaythread::SleepThread()
{
mutex.lock();
waitcondition.wait(&mutex,20);
mutex.unlock();
}

void displaythread::StartDisplay()
{
std::cout<<"RECEIVED START SIGNAL"<<std::endl;
stopped = false;
running = true;
}

void displaythread::StopDisplay()
{
std::cout<<"RECEIVED STOP SIGNAL"<<std::endl;
stopped = true;
running = false;
}

bool displaythread::IsDisplayActive() const
{
return running;
}

void displaythread::Check()
{
std::cout<<"SIGNAL FROM GUI RECEIVED"<<std::endl;
}

display.h

class display : public QWidget
{
Q_OBJECT
public:
explicit display(QWidget *parent = 0);
~display();

signals:

public slots:

private:
void paintEvent(QPaintEvent *);

IplImage *image_opencvBGR,*image_opencvRGB;
QImage image;
CvCapture *webcam;

display.cpp

display::display(QWidget *parent) :
QWidget(parent)
{
image_opencvRGB = cvCreateImage(cvSize(640,480),8,3);
webcam = cvCaptureFromCAM(-1);
}

display::~display()
{
cvReleaseCapture(&webcam);
}

void display::paintEvent(QPaintEvent *)
{
//std::cout<<"IN PAINT LOOP"<<std::endl;
image_opencvBGR = cvQueryFrame(webcam);

cvCvtColor(image_opencvBGR,image_opencvRGB,CV_BGR2RGB);
image = QImage((const unsigned char*)image_opencvRGB->imageData,image_opencvRGB->width,image_opencvRGB->height,QImage::Format_RGB888);
QRectF target(0.0,0.0,image.width(),image.height());
QRectF source(0.0,0.0,image.width(),image.height());
QPainter painter(this);
painter.drawImage(target,image,source);
}

ВЫХОД :

ПОЛУЧЕННЫЙ СИГНАЛ ПРОЦЕССА СТАРТА

Однако, за исключением слота Process, никакой другой слот не работает, когда сигналы исходят из основного интерфейса, т. Е. MainWindow … это из-за команды movetoThread? Донно, где я иду не так ..

1

Решение

Ответ прост: Qwidgets не работает вне основного потока. Таким образом, вы не можете выполнить код GUI, используя displaythread,

Кроме того, ваш цикл while может вызвать проблемы (я знаю, что переменная является изменчивой, но у меня нет времени, чтобы правильно проанализировать, если она верна)

Увидеть документация для дополнительной информации.

PS: Кажется, вы перестарались. Переработайте весь ваш дизайн. Операции с графическим интерфейсом в основном потоке. Используйте темы только для вычислений. Если для связи между потоком и доступа к их переменным используются только сигналы и слоты, вам не нужны механизмы блокировки.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]