Доброе утро ребята. Я написала класс и мне нужно его использовать в потоке. Я создаю указатель на класс в фун-и run() потока и соединяю его сигнал со слотом в классе потока. Но вот проблема, когда запускаю приложение оно падает со следующим сообщением об ошибке:
ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file kernel/qwidget.cpp, line 1299
Я так понимаю он мне говорит что widget я должна создать в потоке, но я же его там создала!
Вот код класса(класс у меня синглетон) который мне нужно использовать в потоке:
#ifndef WINAPIUSER_H
#define WINAPIUSER_H
#include <QWidget>
#include <Windows.h>
#include <Wtsapi32.h>
#include <winbase.h>
#include <QLibrary>
#include <QDebug>
class winAPIUser : public QWidget
{
Q_OBJECT
public:
static winAPIUser* instance();
/// метод блокирующий учетную запись пользователя
/// @return возвращает true если действие произошло успешно и в противном случае возвращает false
bool screenLock();
/// метод проверяющий заблокирована ли учетная запись пользователя
/// @return возвращает true если учетная запись заблокирована и в противном случае возвращает false
bool IsScreenLock();
protected:
/// виртуальный метод переопределяющий поведения окна QWidget в ответ на сообщения от ОС
bool winEvent(MSG *message, long *result);
/// метод - регистрирует в системе окно приложения, которое будет получать уведомления о действиях пользователя, касающиеся его учетной записи
void sendMessageOfActionUser();
private:
explicit winAPIUser(QWidget *parent = 0);
QLibrary m_user32Library;
QLibrary m_wtsapi32Library;
/// статический указатель на класс
static winAPIUser* s_winApi;
/** прототип для winAPI фун-и WTSRegisterSessionNotification*/
typedef bool (*PrototypeWTSRegisterSessionNotification)(HWND,DWORD);
PrototypeWTSRegisterSessionNotification WTSRegisterSessionNotification;
/** прототип для winAPI фун-и WTSUnRegisterSessionNotification*/
typedef bool (*PrototypeWTSUnRegisterSessionNotification)(HWND);
PrototypeWTSUnRegisterSessionNotification WTSUnRegisterSessionNotification;
/** прототип для winAPI фун-и LockWorkStation*/
typedef BOOL (*PrototypeLockWorkStation)();
PrototypeLockWorkStation LockWorkStation;
signals:
/// сигнал информирующий о блокировке/разблокировки учетной записи
bool userScreenLock(bool);
public slots:
};
#endif // WINAPIUSER_H
#define _WIN32_WINNT 0x0501
#include "winapiuser.h"
winAPIUser::winAPIUser(QWidget *parent) :
QWidget(parent)
{
/*загружаем dll */
m_wtsapi32Library.setFileName("wtsapi32");
if (!m_wtsapi32Library.load()) qDebug()<<QString::fromLocal8Bit("ошибка загрузки библиотеки wtsapi32, пишем в лог-файл");
else {
// импортируем фун-ю из библиотеки
WTSRegisterSessionNotification = (PrototypeWTSRegisterSessionNotification) m_wtsapi32Library.resolve("WTSRegisterSessionNotification");
if (!WTSRegisterSessionNotification)
qDebug()<<QString::fromLocal8Bit("ошибка импорта фун-и из библиотеки wtsapi32, пишем в лог-файл");
// импортируем ещё одну фун-ю из библиотеки
WTSUnRegisterSessionNotification = (PrototypeWTSUnRegisterSessionNotification) m_wtsapi32Library.resolve("WTSUnRegisterSessionNotification");
if (!WTSUnRegisterSessionNotification)
qDebug()<<QString::fromLocal8Bit("ошибка импорта фун-и из библиотеки wtsapi32, пишем в лог-файл");
}
/*загружаем dll */
m_user32Library.setFileName("user32");
if (!m_user32Library.load())
qDebug()<<QString::fromLocal8Bit("ошибка загрузки библиотеки user32, пишем в лог-файл");
else {
LockWorkStation = (PrototypeLockWorkStation) m_user32Library.resolve("LockWorkStation");
if (!LockWorkStation)
qDebug()<<QString::fromLocal8Bit("ошибка импорта фун-и из библиотеки wtsapi32, пишем в лог-файл");
}
this->sendMessageOfActionUser();
}
winAPIUser *winAPIUser::s_winApi = 0;
winAPIUser* winAPIUser::instance(){
if (!s_winApi) s_winApi = new winAPIUser();
return s_winApi;
}
bool winAPIUser::IsScreenLock(){
return true;
}
bool winAPIUser::winEvent(MSG *message, long *result){
if (message->message == WM_WTSSESSION_CHANGE) {
qDebug() << "WM_WTSSESSION_CHANGE received.";
switch (message->wParam) {
case WTS_SESSION_LOCK :
// qDebug() << "Seesion locked.";
emit userScreenLock(true);
break;
case WTS_SESSION_UNLOCK :
//qDebug() << "Seesion unlocked.";
emit userScreenLock(false);
break;
default :
;
}
}
return QWidget::winEvent(message, result);
}
void winAPIUser::sendMessageOfActionUser(){
WTSRegisterSessionNotification(winAPIUser::winId(),0);
}
Вот функ-я run() потока:
void MouseTrackThread::run(){
winAPIUser *blockWindow = winAPIUser::instance();
connect(blockWindow,SIGNAL(userScreenLock(bool)),this,SLOT(screenLock(bool)));
keyboard->setConnected(true);
mouse->setHook();
// создаём таймер для сбора инф-я каждую минуту
QTimer *timer = new QTimer;
connect(timer,SIGNAL(timeout()),this,SLOT(returnStatistics()));
timer->setInterval(60000);
timer->start();
}
Если закоментирую создание класса внутри потока всё работает. Причём если создаю этот класс в главном потоке, то всё работает! Как мне решить мою проблему? Мне всё-таки нужно работать с этим классом в фоновом потоке.