Hi,

From http://doc.trolltech.com/4.4/threads.html, I found that
Note that QCoreApplication::exec() must always be called from the main thread (the thread that executes main()), not from a QThread. In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations.

but in the attached application, I tried creating a linux thread from main and tries to call exec from the spawned thread and exec works.
I guess as per above line, exec() should only be calling from thread running main() and not from the spawned thread, am I right?
My question is is any thread a main thread (even though it's not running main()) and therefore can call exec() so long it's not spawned by QThread api?

Qt Code:
  1. #include <pthread.h>
  2. #include <Qt>
  3. #include <QtCore>
  4. #include <QtGui>
  5. #include <QPainter>
  6. #include <QWidget>
  7. #include <QImage>
  8.  
  9. class QPen;
  10. class QBrush;
  11. class QImage;
  12.  
  13. #define SCREEN_X_RESOLUTION 800
  14. #define SCREEN_Y_RESOLUTION 600
  15.  
  16. struct qtimagedesc {
  17. };
  18. typedef struct qtimagedesc QtImageDesc;
  19.  
  20. QtImageDesc *QtImageDescPool = NULL;
  21. bool initDone = false;
  22.  
  23. #define qtApp ((QtApplication *)qApp)
  24. void threadfunc(void *arg);
  25. void AWT_drawline(int x1, int y1, int x2, int y2);
  26. void AWT_drawrect(int x, int y, int w, int h);
  27. void getQtColorModel();
  28. void Qtexec();
  29.  
  30.  
  31. QImage img(SCREEN_X_RESOLUTION,SCREEN_Y_RESOLUTION,QImage::Format_ARGB32);
  32.  
  33. class QtWindow : public QWidget
  34. {
  35. QBitmap transMask;
  36.  
  37. public:
  38. QtWindow(int flags,
  39. const char *name = "Sun AWT/Qt",
  40. QWidget *parent = NULL) ;
  41. virtual void setMask(const QBitmap &);
  42. virtual void paintEvent(QPaintEvent *);
  43.  
  44. };
  45.  
  46. class QtApplication : public QApplication {
  47. public :
  48. QtApplication(int &argc, char **argv);
  49. int exec(); //overloadded exec from QApplication
  50. };
  51.  
  52. class QtScreen
  53. {
  54. protected :
  55. int m_x;
  56. int m_y;
  57. int m_width;
  58. int m_height;
  59. QtWindow *m_window;
  60. bool m_bounds_restricted;
  61. /* virtual char **getArgs(int *argc);
  62.   virtual void computeBounds();
  63.   virtual void createQtWindow();
  64.   virtual void windowShown();
  65. */
  66.  
  67. public :
  68. QtScreen();
  69. bool init();
  70. /* void close();
  71.   void showWindow();
  72.   void setMouseCursor(int cursor);
  73.   void beep();
  74.   int width();
  75.   int height();
  76.   int dotsPerInch();
  77.   QtWindow *window();
  78.   int x();
  79.   int y();
  80. */
  81. };
  82.  
  83. class QtScreenFactory
  84. {
  85. static QtScreen *theScreen;
  86. public:
  87. static QtScreen *getScreen();
  88. };
  89.  
  90.  
  91. QtWindow *m_window;
  92. QtScreen *QtScreenFactory::theScreen = NULL;
  93. QtApplication::QtApplication(int &argc, char **argv) : QApplication(argc, argv) {
  94. }
  95.  
  96. int
  97. QtApplication::exec(void) {
  98. printf("QApplication exec called %x\n", pthread_self());
  99. QApplication::exec();
  100. printf("QApplication exec done\n");
  101. }
  102.  
  103. QtWindow::QtWindow(int flags, const char *name, QWidget *parent) :
  104. QWidget(parent, (Qt::WindowFlags)flags)
  105. {
  106. setMouseTracking(true);
  107. }
  108.  
  109. void QtWindow::setMask(const QBitmap &bm)
  110. {
  111. printf("QtWindow::setMask\n");
  112. }
  113.  
  114. void
  115. QtWindow::paintEvent(QPaintEvent *event)
  116. {
  117. printf("paintEvent called\n");
  118. #if 0
  119. QPen *qp = new QPen();
  120. QColor c(0xffff0000);
  121. qp->setColor(c);
  122. QBrush *qb = new QBrush();
  123. QPainter p(this);
  124. p.setCompositionMode(QPainter::CompositionMode_SourceOver);
  125. p.setPen(*qp);
  126. p.setClipRect(0,0,800,600);
  127. p.drawLine(30,135,790,135);
  128. #endif
  129. QPainter p(QtImageDescPool[0].qpd);
  130. QPoint pt(0,0);
  131. p.drawImage(pt, img);
  132. }
  133.  
  134. int main(int argc, char **argv)
  135. {
  136. pthread_t tid;
  137. printf("main thread %x, argc %d, argv %s\n",pthread_self(), argc, *argv);
  138. #if 1
  139. pthread_create(&tid, NULL, (void *(*)(void *))threadfunc, NULL);
  140. #endif
  141. while(!initDone);
  142. AWT_drawline(0,599,799,599);
  143. usleep(1000);
  144. AWT_drawrect(30,135,190,100);
  145. while(true) {}
  146. // img = new QImage(800,600,QImage::Format_ARGB32);
  147. }
  148.  
  149. QtScreen *
  150. QtScreenFactory::getScreen() {
  151. printf("QtScreenFactory::getScreen()\n");
  152. if ( QtScreenFactory::theScreen == NULL ) {
  153. QtScreenFactory::theScreen = new QtScreen();
  154. if(QtScreenFactory::theScreen != NULL) {
  155. QtScreenFactory::theScreen->init();
  156. }
  157. }
  158. return QtScreenFactory::theScreen;
  159. }
  160.  
  161. QtScreen::QtScreen()
  162. {
  163. printf("QtScreen::QtScreen()\n");
  164. QtImageDescPool = (QtImageDesc *) calloc(sizeof(QtImageDesc), 128);
  165. }
  166.  
  167. void getQtColorModel()
  168. {
  169. int depth = 0;
  170. int amask=0,rmask=0,gmask=0,bmask=0;
  171.  
  172. QWidget *d = QApplication::desktop();
  173. depth = d->depth();
  174. printf ("Depth = %d\n", depth);
  175. switch(depth) {
  176. case 32:
  177. amask = 0xff000000;
  178. case 24:
  179. rmask = 0x00ff0000;
  180. gmask = 0x0000ff00;
  181. bmask = 0x000000ff;
  182. break;
  183. }
  184. }
  185.  
  186. void Qtexec()
  187. {
  188. qtApp->exec();
  189. }
  190.  
  191. bool
  192. QtScreen::init()
  193. {
  194. printf("QtScreen::init() %x\n", pthread_self());
  195. int m_x = 0,m_y=0,m_width=SCREEN_X_RESOLUTION,m_height=SCREEN_Y_RESOLUTION;
  196.  
  197. int argc = 1;
  198. // char *argv[3] = {"a.out", "-qws", NULL};
  199.  
  200. char **argv = (char**)malloc(sizeof(char**) * 2);
  201. argv[0] = (char *)malloc(sizeof(char) * 128);
  202. argv[1] = NULL;
  203. strcpy(argv[0], "cvm");
  204.  
  205. new QtApplication(argc, argv);
  206. QRect screen_bounds = QApplication::desktop()->frameGeometry();
  207. m_window = new QtWindow(Qt::FramelessWindowHint|Qt::Window);
  208. printf("m_window %x\n", this->m_window);
  209. QBitmap bitmap(m_width, m_height);
  210. m_window->setMask(bitmap);
  211. qtApp->setActiveWindow(this->m_window);
  212. this->m_window->move(0,0);
  213. this->m_window->setFixedSize(SCREEN_X_RESOLUTION, SCREEN_Y_RESOLUTION);
  214. this->m_window->show();
  215.  
  216. QtImageDescPool[0].qpd = this->m_window;
  217.  
  218. getQtColorModel();
  219. initDone = true;
  220.  
  221. }
  222.  
  223.  
  224. void threadfunc(void *arg)
  225. {
  226. printf("threadfunc called\n");
  227. QtScreen *screen = QtScreenFactory::getScreen();
  228. Qtexec();
  229. }
  230.  
  231. void
  232. AWT_drawline(int x1, int y1, int x2, int y2)
  233. {
  234. #if 0
  235. QPen *qp = new QPen();
  236. QBrush *qb = new QBrush();
  237. QPainter p(qpd);
  238. p.setCompositionMode(QPainter::CompositionMode_SourceOver);
  239. p.setPen(*qp);
  240. p.setClipRect(0,0,800,600);
  241. p.drawLine(30,135,790,135);
  242. #endif
  243. printf("drawline called\n");
  244. QPainter p(&img);
  245. p.setCompositionMode(QPainter::CompositionMode_SourceOver);
  246. QPen *qp = new QPen();
  247. QColor c(0xffff0000);
  248. qp->setColor(c);
  249. QBrush *qb = new QBrush();
  250. p.setPen(*qp);
  251. p.setClipRect(0,0,SCREEN_X_RESOLUTION,SCREEN_Y_RESOLUTION);
  252. p.drawLine(x1, y1, x2, y2);
  253. printf("m_window %x\n", ((QtWindow *)QtImageDescPool[0].qpd));
  254. //((QtWindow *)arg)->update(0,0,800,600);
  255. ((QtWindow *)QtImageDescPool[0].qpd)->update(0,0,SCREEN_X_RESOLUTION,SCREEN_Y_RESOLUTION);
  256. }
  257.  
  258. void
  259. AWT_drawrect(int x, int y, int w, int h)
  260. {
  261. printf("drawrect called\n");
  262. QPainter p(&img);
  263. p.setCompositionMode(QPainter::CompositionMode_SourceOver);
  264. QPen *qp = new QPen();
  265. QColor c(0xffff0000);
  266. qp->setColor(c);
  267. p.setPen(*qp);
  268. p.setClipRect(0,0,800,600);
  269. p.drawRect(x, y, w, h);
  270. printf("m_window %x\n", ((QtWindow *)QtImageDescPool[0].qpd));
  271. //((QtWindow *)arg)->update(0,0,800,600);
  272. ((QtWindow *)QtImageDescPool[0].qpd)->update(0,0,SCREEN_X_RESOLUTION,SCREEN_Y_RESOLUTION);
  273. }
To copy to clipboard, switch view to plain text mode