'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_OBJECT

    public:
    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&#40;&#41;;
    

    }
    @


  • Lifetime Qt Champion

    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(...).

    1. create the thead's object
    2. call connect(...)
    3. 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();
    }@



  • Thank u @treenn, that sorted it out.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.