'QMessageBox:: критический': ни одна из 4 перегрузок не может преобразовать все типы аргументов
Я хочу отображать сообщение об ошибке всякий раз, когда мой независимый поток встречает слово "alert1" в определенном.txt файле. Но я получаю вышеуказанную ошибку внутри monitorForAlerts() внутри файла mythread.cpp. Строка ожидаемо выполняется, если бы я поместил ее в dialog.cpp. Так что я думаю, это связано с ненаследованием этого объекта. Можете ли вы посоветовать мне, как решить эту ошибку для данного кода?
Вот код: 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();
}
ПОСЛЕДНИЕ ОБНОВЛЕНИЯ ************************************************ *********************
Привет, Златомир, я решил последовать твоему первому совету. Я создал сигнал, что поток будет излучать и подключить его к слоту для QDialog. Пожалуйста, дайте мне знать, если мое понимание верно, потому что я не знаю, где реализовать connect(), так как сигнал объявлен в mythread.h и слот в dialog.h. Аргументом типа соединения для connect является Qt::QueuedConnection, так что элементы gui из другого потока отличаются от основного потока. НЕ созданы. Это утверждение правильно? и где мне это разместить?
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"));
}
Теперь, если это было правильно, как я могу реализовать connect () и в каком файле?
1 ответ
Первый аргумент - проблема, в вашем случае this
это не хороший аргумент, потому что там this
это указатель на MyThread
экземпляр и MyThread
не является QWidget (не является производным от QWidget).
Чтобы решить эту проблему, вы можете показать QMessageBox::critical
из слота в главном окне Dialog
класс в вашем коде, там вы передаете экземпляр главного окна, который является QWidget) и подключите этот слот с сигналом, который вы излучаете из вашего потока, убедитесь, что аргумент типа соединения для подключения является Qt::QueuedConnection
, так что вы не пытаетесь создавать элементы графического интерфейса из другого потока, отличного от основного потока.
Другой вариант - проверить данные перед запуском второго потока и сообщить пользователю, что он должен предоставить нужные файлы.
LE: Также проверьте документацию QThread для рекомендуемого способа использования класса, теперь рекомендуется не наследовать от QThread.
LE2 - ответ на обновление Это соединение может быть сделано везде, где вы можете иметь два экземпляра, которые вы хотите подключить, в вашем случае main.cpp
это хорошее место для подключения тех (не забудьте полностью указать название для подключения: QObject::connect
):
//...
MyThread mThread1;
mThread1.name = "mThread1";
mThread1.start();
Dialog w;
QObject::connect( &mThread1, SIGNAL(alertSignal(QString)), &w, SLOT(alertSlot(QString)), Qt::QueuedConnection);
w.show();
//...