Results 1 to 6 of 6

Thread: ASSERT failure in QWidget: " Widgets must be created in GUI Thread"

  1. #1
    Join Date
    Aug 2012
    Posts
    3
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default ASSERT failure in QWidget: " Widgets must be created in GUI Thread"

    I realize other threads exist concerning this topic, but none of the responses apply to my situation.
    I am using a QApplication and MainWindow instance to run my GUI from my main() function. I also run a windows API thread out of my main() to use various opencv functions in a separate thread. The strange part is when I remove the windows API thread calls, I don't have this problem, but I am 99% sure I don't call a QWidget in any of the runprog function. Any help would be awesome.

    Here is my main.cpp

    Qt Code:
    1. #include <Windows.h>
    2. #include <WinCon.h>
    3.  
    4. #include <opencv2\core\core.hpp>
    5. #include <opencv2\highgui\highgui.hpp>
    6. #include <opencv2\imgproc\imgproc.hpp>
    7. #include "Alignment.h"
    8. #include "mainwindow.h"
    9. #include "globals.h"
    10.  
    11. #include <QtGui>
    12. #include <QtCore/QCoreApplication>
    13. #include <QApplication>
    14. #include <QMainWindow>
    15. #include <QHBoxLayout>
    16. #include "conio.h"
    17.  
    18. #include <string>
    19. #include <iostream>
    20. #include <stdio.h>
    21. #include <stdlib.h>
    22. #include <time.h>
    23. #include <sstream>
    24.  
    25. DWORD WINAPI runProg(LPVOID args);
    26. HANDLE rThread;
    27. HANDLE rEvent;
    28.  
    29. //Struct for passing data
    30. struct PixelData {
    31. int totalrpixels;
    32. int totalgpixels;
    33. int totalrpixelarea;
    34. int totalgpixelarea;
    35. cv::Point redcenter;
    36. cv::Point greencenter;
    37. };
    38.  
    39. cv::Point getCentroid(cv::Mat);
    40. int runprog();
    41. PixelData getColorSpotInfo(cv::Mat*, cv::Mat*, cv::Mat*);
    42.  
    43.  
    44. int main(int argc, char *argv[])
    45. {
    46. QApplication app(argc, argv);
    47. MainWindow *mainwin = new MainWindow();
    48. mainwin->show();
    49. rEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
    50. rThread = CreateThread(NULL,0,runProg,0,0,&runProgId);
    51. return app.exec();
    52. }
    53.  
    54. int runprog()
    55. {
    56. //Variables
    57. cv::Mat depthimage, depthMap, bgrimage, dark, light, hsvim;
    58. cv::Point gcoord;
    59. cv::Point rcoord;
    60.  
    61. //Color Thresholds
    62. int darkrmax = 230;
    63. int darkrmin = 170;
    64. int darkgmax = 220;
    65. int darkgmin = 150;
    66. int darkbmax = 200;
    67. int darkbmin = 140;
    68. int lightrmax = 150;
    69. int lightrmin = 100;
    70. int lightgmax = 80;
    71. int lightgmin = 30;
    72. int lightbmax = 90;
    73. int lightbmin = 40;
    74.  
    75.  
    76. //Adjust Console Location
    77. HWND hwnds = GetConsoleWindow();
    78. MoveWindow(hwnds,5,5,400,300,TRUE);
    79.  
    80. int rows, cols, centerx, centery;
    81.  
    82. cv::VideoCapture capture(CV_CAP_OPENNI);
    83. capture.grab();
    84.  
    85. capture.retrieve(depthMap,CV_CAP_OPENNI_DEPTH_MAP);
    86. capture.retrieve(bgrimage,CV_CAP_OPENNI_BGR_IMAGE);
    87. cv::cvtColor(bgrimage,hsvim,CV_BGR2HSV);
    88. inRange(hsvim, cv::Scalar(darkbmin, darkgmin, darkrmin), cv::Scalar(darkbmax, darkgmax, darkrmax), dark);
    89. inRange(hsvim, cv::Scalar(lightbmin, lightgmin, lightrmin), cv::Scalar(lightbmax, lightgmax, lightrmax), light);
    90.  
    91. depthMap.convertTo(depthimage, CV_8UC1, 0.05f);
    92. cv::cvtColor(bgrimage,hsvim,CV_BGR2HSV);
    93. cv::imshow("CameraFeed",bgrimage);
    94. cv::imshow("Dark",dark);
    95. cv::imshow("Light",light);
    96. cv::imshow("HSVFeed",hsvim);
    97. cv::imshow("Depth",depthimage);
    98.  
    99. cvMoveWindow("CameraFeed", 5, 300);
    100. cvMoveWindow("Dark", 800, 5);
    101. cvMoveWindow("Light", 800, 300);
    102. cvMoveWindow("HSVFeed", 300, 5);
    103. cvMoveWindow("Depth", 1600, 5);
    104.  
    105. PixelData pixdatcap;
    106.  
    107. while(true){
    108. capture.grab();
    109. capture.retrieve(depthMap,CV_CAP_OPENNI_DEPTH_MAP);
    110. capture.retrieve(bgrimage,CV_CAP_OPENNI_BGR_IMAGE);
    111. depthMap.convertTo(depthimage, CV_8UC1, 0.05f);
    112. cv::cvtColor(bgrimage,hsvim,CV_BGR2HSV);
    113. inRange(hsvim, cv::Scalar(darkbmin, darkgmin, darkrmin), cv::Scalar(darkbmax, darkgmax, darkrmax), dark);
    114. inRange(hsvim, cv::Scalar(lightbmin, lightgmin, lightrmin), cv::Scalar(lightbmax, lightgmax, lightrmax), light);
    115. if(runnow == 1){
    116. pixdatcap = getColorSpotInfo(&dark, &light, &depthMap);
    117. runnow = 0;
    118. }
    119.  
    120. cv::imshow("CameraFeed",bgrimage);
    121. cv::imshow("Dark",dark);
    122. cv::imshow("Light",light);
    123. cv::imshow("HSVFeed",hsvim);
    124. cv::imshow("Depth",depthimage);
    125.  
    126. cv::waitKey(1);
    127.  
    128. }
    129. return 1;
    130.  
    131. }
    132.  
    133. cv::Point getCentroid(cv::Mat img)
    134. {
    135. cv::Point Coord;
    136. cv::Moments mm = cv::moments(img,false);
    137. double moment10 = mm.m10;
    138. double moment01 = mm.m01;
    139. double moment00 = mm.m00;
    140. Coord.x = int(moment10 / moment00);
    141. Coord.y = int(moment01 / moment00);
    142. return Coord;
    143. }
    144.  
    145.  
    146. PixelData getColorSpotInfo(cv::Mat *greenmat, cv::Mat *redmat, cv::Mat *depthdata){
    147. cv::Mat green = *greenmat;
    148. cv::Mat red = *redmat;
    149. cv::Mat depdat = *depthdata;
    150. int totalgpix = 0;
    151. int totalrpix = 0;
    152. int avgdepthg = 0;
    153. int avgdepthr= 0;
    154. int totaldepthr = 0;
    155. int totaldepthg = 0;
    156.  
    157. PixelData pixdat;
    158.  
    159. pixdat.redcenter = getCentroid(red);
    160. pixdat.greencenter = getCentroid(green);
    161. for(int x = 0; x < green.rows; x++){
    162. for(int y = 0; y < green.cols; y++){
    163. if(((uchar*)(green.data + green.step*x))[y] != 0){
    164. totalgpix++;
    165. totaldepthg += ((uchar*)(depdat.data + depdat.step*x))[y];
    166. }
    167. if(((uchar*)(red.data + red.step*x))[y] != 0){
    168. totalrpix++;
    169. totaldepthr += ((uchar*)(depdat.data + depdat.step*x))[y];
    170. }
    171. }
    172. }
    173. avgdepthr = totaldepthr/totalrpix;
    174. avgdepthg = totaldepthg/totalgpix;
    175.  
    176. pixdat.totalgpixels = totalgpix;
    177. pixdat.totalrpixels = totalrpix;
    178.  
    179. pixdat.totalgpixelarea = (totalgpix*avgdepthg)/100;
    180. pixdat.totalrpixelarea = (totalrpix*avgdepthr)/100;
    181.  
    182. return pixdat;
    183.  
    184. }
    185.  
    186. DWORD WINAPI runProg(LPVOID args) {
    187. DWORD retint;
    188. OutputDebugStringW(L"run thread started. ");
    189. try {
    190. retint = runprog();
    191. }
    192. catch( char * str ) {
    193. std::cout << "Exception raised: " << str << '\n';
    194. }
    195. OutputDebugStringW(L"run thread leaving. ");
    196. SetEvent(rEvent);
    197. return retint;
    198. }
    To copy to clipboard, switch view to plain text mode 

    And my mainwindow.cpp

    Qt Code:
    1. #include "mainwindow.h"
    2. #include "globals.h"
    3. #include <Windows.h>
    4. #include "ui_mainwindow.h"
    5.  
    6. #include <QtGui>
    7. #include <iostream>
    8. #include <stdio.h>
    9. #include <stdlib.h>
    10.  
    11. void MainWindow::RunHandle()
    12. {
    13. runnow = 1;
    14. system("cls");
    15. }
    16.  
    17. void MainWindow::QuitHandle()
    18. {
    19. OutputDebugStringW(L"main window exit.");
    20. quitnow = 1;
    21. Sleep(100);
    22. qApp->quit();
    23. }
    24.  
    25. void MainWindow::OptionHandlePos(int buttonIdP)
    26. {
    27. if(buttonIdP == 1){
    28. PosVar = 1;
    29. }
    30. else if(buttonIdP == 2){
    31. PosVar = 2;
    32. }
    33. else if(buttonIdP == 3){
    34. PosVar = 3;
    35. }
    36. else if(buttonIdP == 4){
    37. PosVar = 4;
    38. }
    39. else{
    40. PosVar = 1;
    41. }
    42. }
    43.  
    44. void MainWindow::OptionHandleFull(int buttonIdF)
    45. {
    46. if(buttonIdF == 1){
    47. FullVar = 1;
    48. }
    49. else if(buttonIdF == 2){
    50. FullVar = 2;
    51. }
    52. else{
    53. FullVar = 1;
    54. }
    55. }
    56.  
    57. MainWindow::MainWindow(QWidget *parent) :
    58. QMainWindow(parent)
    59. {
    60.  
    61. //Position Menu
    62. QGroupBox *PosGroup = new QGroupBox("Position Menu");
    63. QRadioButton *Pos1 = new QRadioButton("Top Right");
    64. QRadioButton *Pos2 = new QRadioButton("Top Left (default)");
    65. QRadioButton *Pos3 = new QRadioButton("Bottom Right");
    66. QRadioButton *Pos4 = new QRadioButton("Bottom Left");
    67. Pos2->setChecked(true);
    68. QVBoxLayout *PosBox = new QVBoxLayout;
    69. PosBox->addWidget(Pos1);
    70. PosBox->addWidget(Pos2);
    71. PosBox->addWidget(Pos3);
    72. PosBox->addWidget(Pos4);
    73. PosBox->addStretch(1);
    74. PosGroup->setLayout(PosBox);
    75. //mapping radio buttons
    76. QSignalMapper* SigMapPos = new QSignalMapper(this);
    77. connect(SigMapPos, SIGNAL(mapped(int)), this, SLOT(OptionHandlePos(int)));
    78. SigMapPos->setMapping(Pos1, 1);
    79. SigMapPos->setMapping(Pos2, 2);
    80. SigMapPos->setMapping(Pos3, 3);
    81. SigMapPos->setMapping(Pos4, 4);
    82. connect(Pos1, SIGNAL(clicked()), SigMapPos, SLOT(map()));
    83. connect(Pos2, SIGNAL(clicked()), SigMapPos, SLOT(map()));
    84. connect(Pos3, SIGNAL(clicked()), SigMapPos, SLOT(map()));
    85. connect(Pos4, SIGNAL(clicked()), SigMapPos, SLOT(map()));
    86.  
    87. //Make Full Screen Menu
    88. QGroupBox *FullGroup = new QGroupBox("Toggle Full Screen");
    89. QRadioButton *Full1 = new QRadioButton("Normal (default)");
    90. QRadioButton *Full2 = new QRadioButton("Full");
    91. Full1->setChecked(true);
    92. QVBoxLayout *FullBox = new QVBoxLayout;
    93. FullBox->addWidget(Full1);
    94. FullBox->addWidget(Full2);
    95. FullBox->addStretch(1);
    96. FullGroup->setLayout(FullBox);
    97. //mapping radio buttons
    98. QSignalMapper* SigMapFull = new QSignalMapper(this);
    99. connect(SigMapFull, SIGNAL(mapped(int)), this, SLOT(OptionHandleFull(int)));
    100. SigMapFull->setMapping(Full1, 1);
    101. SigMapFull->setMapping(Full2, 2);
    102. connect(Full1, SIGNAL(clicked()), SigMapFull, SLOT(map()));
    103. connect(Full2, SIGNAL(clicked()), SigMapFull, SLOT(map()));
    104.  
    105.  
    106. //Reset/Close Application buttons
    107. QGroupBox *RCGroup = new QGroupBox("Actions");
    108. QPushButton* ButtonRun= new QPushButton("Run");
    109. QPushButton* ButtonQuit = new QPushButton("Close");
    110. QHBoxLayout *RCBox = new QHBoxLayout;
    111. RCBox->addWidget(ButtonRun);
    112. RCBox->addWidget(ButtonQuit);
    113. RCBox->addStretch(1);
    114. RCGroup->setLayout(RCBox);
    115. connect(ButtonQuit, SIGNAL(clicked()), this, SLOT(QuitHandle()) );
    116. connect(ButtonRun, SIGNAL(clicked()), this, SLOT(RunHandle()) );
    117.  
    118. //Combine all menu options
    119. QVBoxLayout *MenuBox = new QVBoxLayout;
    120. MenuBox->addWidget(PosGroup);
    121. MenuBox->addWidget(FullGroup);
    122. MenuBox->addWidget(RCGroup);
    123. QWidget *widget = new QWidget(this);
    124. widget->setLayout(MenuBox);
    125. setCentralWidget(widget);
    126.  
    127. }
    To copy to clipboard, switch view to plain text mode 

    And globals.h/cpp is a basic global variables thing but I doubt the global stuff has anything to do with it though.

    I like to think I know QT fairly well but for the life of me I cannot figure out what is going on. Any help, even as much as copying the code and running it to see if its just my system would be appreciated greatly.

    Thanks,
    Rod

  2. #2
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: ASSERT failure in QWidget: " Widgets must be created in GUI Thread"

    a call stack would be useful.

    fyi, the following headers are not standard:
    #include "conio.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  3. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: ASSERT failure in QWidget: " Widgets must be created in GUI Thread"

    If you remove the lines getting and moving the console does the problem go away? Is the console window the one provided by Qt?

  4. #4
    Join Date
    Aug 2012
    Posts
    3
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: ASSERT failure in QWidget: " Widgets must be created in GUI Thread"

    Thanks for the quick replies.

    The call trace didn't really lead anywhere so I just threw in a slew of print statements and found out it was the cv::imshow() call. It seems like when you build opencv with qt, the opencv imshow windows use qt code and so the other qt thread believes the imshow window is also making a widget? Have you heard of this before?

    Anyways, I believe thats the issue so I'm trying some work-arounds. Also what do you mean those headers are not standard, I thought stdio and stdlib were?

    And ChrisW67, no the console-move command is moving win32 application console.

  5. #5
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: ASSERT failure in QWidget: " Widgets must be created in GUI Thread"

    correct header names are cstdlib, cstdio and ctime
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: ASSERT failure in QWidget: " Widgets must be created in GUI Thread"

    What's actually the reason for trying to move the OpenCV window from within a worker thread?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 3
    Last Post: 26th September 2012, 21:21
  2. ASSERT: "bitmap" in file image\qnativeimage.cpp, line 114
    By DusanDusan in forum Qt Programming
    Replies: 2
    Last Post: 23rd May 2012, 07:30
  3. Replies: 1
    Last Post: 5th February 2011, 22:14
  4. ASSERT: "w->testAttribute(Qt::WA_WState_Created)"
    By majcia in forum Qt Programming
    Replies: 5
    Last Post: 16th December 2010, 16:42
  5. QWidget with "encapsulated thread"
    By phixx in forum Qt Programming
    Replies: 5
    Last Post: 3rd March 2008, 20:42

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.