'QMessageBox::critical' : none of the 4 overloads could convert all the argument types
-
I want to display an error message whenever my independent thread encounters the word "alert1" in a specific .txt file. But I get the above error inside the monitorForAlerts() inside mythread.cpp file. The line expectedly executes if I were to place it inside dialog.cpp. So I guess this is due to non-inheritance of this object. Can you please advise me how to solve this error for the given code?
Here is the code:
dialog.h
@
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QtCore>
#include "mythread.h"
namespace Ui {
class Dialog;
}class Dialog : public QDialog
{
Q_OBJECTpublic:
explicit Dialog(QWidget *parent = 0);
~Dialog();public slots:
private:
Ui::Dialog *ui;private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
};#endif // DIALOG_H
@mythread.h
@
#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>
#include <QtCore>
#include <QDebug>
#include <QFile>
#include <Windows.h>
#include <QMessageBox>
#include <QTimer>
#define ALERTS_MESSAGE_STORAGE_PATH "E:\QT1\simpleGUIThread2\simpleGUIThread2\usbAlert.txt"
#define TIMER_VALUE 500
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void run();
QString name;
void monitorForAlerts();
int exec();public slots:
signals:
void testSignal(QString message);public slots:
};
#endif // MYTHREAD_H
@dialog.cpp
@
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}Dialog::~Dialog()
{
delete ui;
}void Dialog::on_pushButton_clicked()
{
ui->label->show();
}void Dialog::on_pushButton_2_clicked()
{
ui->label->hide();
}
@mythread.cpp
@
#include "mythread.h"
#include "dialog.h"
MyThread::MyThread(QObject *parent) :
QThread(parent)
{
}void MyThread::run()
{
exec();
}int MyThread::exec()
{
while(1)
{
monitorForAlerts();
emit(testSignal("hello world!!"));
sleep(1);
}
}void MyThread::monitorForAlerts()
{
QString response = ALERTS_MESSAGE_STORAGE_PATH;
QFile resp(response);
resp.open(QIODevice::WriteOnly);
resp.close();
QFile resp1(response);
char buf[121];
char buf1[] = "alert1";
char buf2[] = "alert2";resp1.open(QIODevice::ReadOnly); while(resp1.size() == 0) { Sleep(3000); } qint64 lineLength = resp1.readLine(buf, sizeof(buf)); resp1.close(); if(strcmp(buf,buf1) == 0) { QFile::remove(ALERTS_MESSAGE_STORAGE_PATH); qDebug()<<"warning 1!!"; QMessageBox::critical(this,tr("ERROR"),tr("Large change in illumination.\nPlease re-capture reference image.\n")); } if(strcmp(buf,buf2) == 0) { QFile::remove(ALERTS_MESSAGE_STORAGE_PATH); qDebug()<<"warning 2!!"; QMessageBox::critical(this,tr("ERROR"),tr("The camera position has been moved or an object is obscuring its view.\nPlease check the device.\n")); }
}
@main.cpp
@
#include "dialog.h"
#include <QApplication>
#include "mythread.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);MyThread mThread1; mThread1.name = "mThread1"; mThread1.start(); Dialog w; w.show(); return a.exec();
}
@ -
Hi,
First thing, GUI manipulation cannot be done outside the main thread AKA the GUI thread. You should emit a signal from your thread to your Dialog and show the QMessageBox there.
There error message comes from the fact that you are trying to give a QObject as the parent of the QMessageBox which can only have a QWidget as a parent.
I would also recommend that you take a look at the QThread latest documentation to see the various possible implementation. Using a worker object with a timer would be cleaner in your case.
Hope it helps
-
Hi SGaist,
I choose to take your 1st advice. I have created a signal that the thread will emit and connect it to a slot for QDialog. Please let me know if my understanding is correct, because I do not know where to implement the connect(), since the signal is declared in mythread.h and the slot in dialog.h. The connection type argument for connect is Qt::QueuedConnection, so that gui elements from another thread different than main-thread.
are NOT created. Is this statement correct? and where do I place this?@
connect( mThread, SIGNAL(alertSignal(QString)), this, SLOT(alertSlot(QString)), Qt::QueuedConnection);
@mythread.h
@
//....
signals:
void alertSignal(QString message);
//....
@dialog.h
@
//....
public slots:
void alertSlot(QString message);
//....
@mythread.cpp
@
//....
if(strcmp(buf,buf1) == 0)
{
QFile::remove(ALERTS_MESSAGE_STORAGE_PATH);
qDebug()<<"warning 1!!";
emit(alertSignal("alert1"));
}
else if(strcmp(buf,buf2) == 0)
{
QFile::remove(ALERTS_MESSAGE_STORAGE_PATH);
qDebug()<<"warning 2!!";
emit(alertSignal("alert2"));
}
@dialog.cpp
@
void Dialog::alertSlot(QString message)
{
if(strcmp(message, "alert1"))
QMessageBox::critical(this,tr("ERROR"),tr("Large change in illumination.\nPlease re-capture reference image.\n"));
else if(strcmp(message, "alert2"))
QMessageBox::critical(this,tr("ERROR"),tr("The camera position has been moved or an object is obscuring its view.\nPlease check the device.\n"));
}
@Now if this were correct, how do i implement the connect() and in which file?
-
Better create and start your thread in the dialog's constructor Dialog::Dialog(...).
- create the thead's object
- call connect(...)
- start the thread
So it should be something like this:
@Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
mThread1=new MyThread(this); //add the field "MyThread *mThread1" to your dialogs definition.
mThread1->setObjectName("mThread1");
connect( mThread1, SIGNAL(alertSignal(QString)), this, SLOT(alertSlot(QString)), Qt::QueuedConnection);
mThread1->start();
}@