PDA

View Full Version : Widgets must be created in the GUI thread.



Thành Viên Mới
3rd July 2011, 19:20
hi all, i dont understand why my program error Widgets must be created in the GUI thread.

it use Qthread loop WaitForSingleObject(hEvent, INFINITE);

when i run test-gui-event-error project and after run sendevent project then it error :

6625


message error: ASSERT failure in QWidget: "Widgets must be created in the GUI

note: my source code project: Desktop.zip --> you must run test-gui-event-error project and after run sendevent , it will show error message
thread.", file kernel/qwidget.cpp

mvuori
3rd July 2011, 20:05
hi all, i dont understand why my program error Widgets must be created in the GUI thread.

it use Qthread loop WaitForSingleObject(hEvent, INFINITE);

I don't understand either, but I do not see any reference to WaitForSingleObject in the C++ source.

ChrisW67
4th July 2011, 01:37
Run you project in your debugger. When is asserts look back through the backtrace of the non-main thread(s) until you find the line in your code that is causing the problem.

Thành Viên Mới
4th July 2011, 16:33
I don't understand either, but I do not see any reference to WaitForSingleObject in the C++ source.

no, haven't you read my source code attach ???



#include "threadwaitforaddgroupevent.h"

ThreadWaitForAddGroupEvent::ThreadWaitForAddGroupE vent()
{
hEvent = CreateEventA(NULL, FALSE, FALSE, EVENT_ADD_NEW_GROUP);
hMapFile = CreateFileMappingA(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // max. object size
BUF_SIZE, // buffer size
MAP_FILE_ADD_NEW_GROUP); // name of mapping object
if (hMapFile == NULL)
{
return ;
}
}

void ThreadWaitForAddGroupEvent::ProcessDataFromMapFile ()
{
HANDLE hMapFile = OpenFileMappingA(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
MAP_FILE_ADD_NEW_GROUP); // name of mapping object
if (hMapFile == NULL)
{
return ;
}
char *pBuf = (char*) MapViewOfFile(
hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);

if (pBuf == NULL)
{
return ;
}
QString dataFromMapFile(pBuf);
QList<QString> lUserNewGroup = dataFromMapFile.split('|');
emit AddNewGroup(lUserNewGroup);

}

void ThreadWaitForAddGroupEvent::run(){
while(1){
WaitForSingleObject(hEvent, INFINITE);
ProcessDataFromMapFile();
}
}

ThreadWaitForAddGroupEvent::~ThreadWaitForAddGroup Event(){
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
}



SendEvent:



#include <QtCore/QCoreApplication>
#include <QtGui/QMessageBox>
#include <QString>
#include <windows.h>

#define BUF_SIZE 1024
#define MAP_FILE_ADD_NEW_GROUP "Local\\MyFileMappingAddNewGroup"
#define EVENT_ADD_NEW_GROUP "Local\\eventaddnewgroup"


int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HANDLE hMapFile;
char* pBuf;

QString qstrDataSend = "ADDKJHGFDSDFGHJ";
hMapFile = OpenFileMappingA(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
MAP_FILE_ADD_NEW_GROUP); // name of mapping object
if (hMapFile == NULL)
{
QMessageBox::information( NULL, "L?i ph?n m?m","L?i OpenFileMapping, B?n hãy kh?i d?ng l?i ph?n m?m" );
return 1;
}
pBuf = (char*) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
QMessageBox::information( NULL, "loi","khong the map view file" );
return 2;
}
CopyMemory((PVOID) pBuf, qstrDataSend.toStdString().data(), qstrDataSend.length());
HANDLE hEvent = OpenEventA(EVENT_ALL_ACCESS, FALSE, EVENT_ADD_NEW_GROUP);
SetEvent(hEvent);
return a.exec();
}

stampede
4th July 2011, 16:42
If you want to use QtGui, then you have to instantiate QApplication object, QCoreApplication is not enough to use message windows, change this


#include <QtCore/QCoreApplication>
...
QCoreApplication a(argc, argv);

to


#include <QApplication>
...
QApplication a(argc, argv);

Thành Viên Mới
8th July 2011, 18:42
thanks you, i was fix Widgets must be created in the GUI thread on SendEvent, but when i run test-gui-event-error project and after run sendevent project then it still error on test-gui-event-error

this is error debug on QtCreator



in c:\ndk_buildrepos\qt-desktop\src\corelib\global\qglobal.cpp
0x6a10e211 <+000>: push %ebp
0x6a10e212 <+001>: mov %esp,%ebp
0x6a10e214 <+003>: sub $0x18,%esp
2027 in c:\ndk_buildrepos\qt-desktop\src\corelib\global\qglobal.cpp
0x6a10e217 <+006>: mov 0x10(%ebp),%eax
0x6a10e21a <+009>: mov %eax,0xc(%esp)
0x6a10e21e <+013>: mov 0xc(%ebp),%eax
0x6a10e221 <+016>: mov %eax,0x8(%esp)
0x6a10e225 <+020>: mov 0x8(%ebp),%eax
0x6a10e228 <+023>: mov %eax,0x4(%esp)
0x6a10e22c <+027>: movl $0x6a2e3e50,(%esp)
0x6a10e233 <+034>: call 0x6a10ebf0 <qFatal(const char *, ...)>
2028 in c:\ndk_buildrepos\qt-desktop\src\corelib\global\qglobal.cpp
0x6a10e238 <+039>: leave
0x6a10e239 <+040>: ret


6644

Thành Viên Mới
10th July 2011, 16:54
can you help me ?

Thành Viên Mới
8th November 2011, 11:13
can you help me ??? :((

nightghost
8th November 2011, 13:03
try to change



connect(tWAGE,SIGNAL(AddNewGroup(QList<QString>)),this,SLOT(prepareAddGroup(QList<QString>)),Qt::DirectConnection );

to


connect(tWAGE,SIGNAL(AddNewGroup(QList<QString>)),this,SLOT(prepareAddGroup(QList<QString>)));

or


connect(tWAGE,SIGNAL(AddNewGroup(QList<QString>)),this,SLOT(prepareAddGroup(QList<QString>)), Qt::QueuedConnection);


see http://doc.trolltech.com/4.5/threads.html#signals-and-slots-across-threads

Thành Viên Mới
8th November 2011, 17:48
it still error


when i play QmessageBOx in Qthread then it still also error

help me resolve

nightghost
8th November 2011, 17:53
Yes of course. Please read http://doc.qt.nokia.com/4.7-snapshot/thread-basics.html



As mentioned, each program has one thread when it is started. This thread is called the "main thread" (also known as the "GUI thread" in Qt applications). The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, work in secondary threads.


To be clear: Its (by the design of Qt) not possible to work with widgets in threads. The work only in the main thread! Inform the main thread from your worker thread to show the message box.