You are not logged in.

Dear visitor, welcome to QtForum.org. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

1

Wednesday, June 27th 2012, 4:15pm

QApplication outside of main

If you're like me and you've been given a large amount of code but you need to add a qt menu to the existing code, you may want a way to deal with adding your gui outside of main(). I realize that every nokia/trolltech documentation states this is improper and should not be done, but unfortunately it's damn near impossible sometimes to rewrite the entire code so that the QT functions can exist in main. After having read multiple sites attempting to accomplish this I wrote my own bit of code to try it out.

Here is my main function

Source code

1
2
3
4
5
6
7
8
9
10
#include "StereoProcessor.h"#include "mainwindow.h"#include "mainthread.h"#include "globals.h"#include "ui_mainwindow.h"
using namespace std;
DWORD WINAPI runQtGUI(LPVOID args);void Run(int, int);int sum;int input;int argc;char **argv;
//void mainthread::run()int main(int rargc, char *rargv[]){	//copy of argc and argv to pass to QMain	argc=rargc;	argv=rargv;
	CreateThread(NULL,0,runQtGUI,0,0,&runQtGUIId);	CreateThread(NULL,0,runProg,0,0,&runProgId);
	while(true){	 if(quitnow == 1){ break;		} }
	std::exit(0);	return 0;}
DWORD WINAPI runQtGUI(LPVOID args) {	try {	 GUI::runQtGUI(argc,argv);	} catch (exception ex) { std::cout << ex.what() << endl; cv::waitKey(); }	return 0;}
DWORD WINAPI runProg(LPVOID args) { try {	 Run(sum,input); } catch (exception ex) { std::cout << ex.what() << endl;	 cv::waitKey();	}	return 0;}
void Run(int sum, int input){	resetnow = 0;	quitnow = 0;	time_t starttime,newtime;	int offset = 0;	int dif = 0;	time(&starttime);	while(true){		time(&newtime);		dif = difftime(newtime,starttime);		if(dif >= offset){			system("cls");			sum = PMDetector+ PMExtractor;			std::cout << "the current sum of your variables is " << sum << " \n";			offset += 1;		}		if(quitnow == 1){			break;		}	}}



</iostream>


Notice WINAPI threads are used to call the QMain function, contained here in MainWindow.cpp, the argc and argv are also passed as copies into the run function


Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "mainthread.h"#include "mainwindow.h"#include "globals.h"#include #include "ui_mainwindow.h"
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 
#include #include #include 
void GUI::MainWindow::ResetHandle(){	system("cls");
	CreateThread(NULL,0,runProg,0,0,&runProgId);    resetnow = 1;}
void GUI::MainWindow::QuitHandle(){	system("cls");	quitnow = 1;	std::exit(0);}

void GUI::MainWindow::OptionHandlePMD(int buttonIdPMD){    if(buttonIdPMD == 1){        PMDetector = 1;    }    else if(buttonIdPMD == 2){        PMDetector = 2;    }    else if(buttonIdPMD == 3){        PMDetector = 3;    }    else if(buttonIdPMD == 4){        PMDetector = 4;    }	else{        PMDetector = 1;    }}
void GUI::MainWindow::OptionHandlePME(int buttonIdPME){    if(buttonIdPME == 1){        PMExtractor = 1;    }    else if(buttonIdPME == 2){        PMExtractor = 2;    }	else{        PMExtractor = 1;    }}

GUI::MainWindow::MainWindow(QWidget *parent) :	QMainWindow(parent){
    //Point Matching Detector Menu Region Setup    QGroupBox *PMDGroup = new QGroupBox("Point Matching Detector");    QRadioButton *pmd1 = new QRadioButton("Use ORB (default)");    QRadioButton *pmd2 = new QRadioButton("Use FAST");    QRadioButton *pmd3 = new QRadioButton("Use MSER");    QRadioButton *pmd4 = new QRadioButton("Use STAR");    pmd1->setChecked(true);    QVBoxLayout *PMDBox = new QVBoxLayout;    PMDBox->addWidget(pmd1);    PMDBox->addWidget(pmd2);    PMDBox->addWidget(pmd3);    PMDBox->addWidget(pmd4);    PMDBox->addStretch(1);    PMDGroup->setLayout(PMDBox);    //mapping radio buttons    SigMapPMD = new QSignalMapper(this);    connect(SigMapPMD, SIGNAL(mapped(int)), this, SLOT(OptionHandlePMD(int)));    SigMapPMD->setMapping(pmd1, 1);    SigMapPMD->setMapping(pmd2, 2);    SigMapPMD->setMapping(pmd3, 3);    SigMapPMD->setMapping(pmd4, 4);    connect(pmd1, SIGNAL(clicked()), SigMapPMD, SLOT(map()));    connect(pmd2, SIGNAL(clicked()), SigMapPMD, SLOT(map()));    connect(pmd3, SIGNAL(clicked()), SigMapPMD, SLOT(map()));    connect(pmd4, SIGNAL(clicked()), SigMapPMD, SLOT(map()));
    //Point Matching Extractor Menu Region Setup    QGroupBox *PMEGroup = new QGroupBox("Point Matching Extractor");    QRadioButton *pme1 = new QRadioButton("Use BRIEF (default)");    QRadioButton *pme2 = new QRadioButton("Use ORB");    pme1->setChecked(true);    QVBoxLayout *PMEBox = new QVBoxLayout;    PMEBox->addWidget(pme1);    PMEBox->addWidget(pme2);    PMEBox->addStretch(1);    PMEGroup->setLayout(PMEBox);    //mapping radio buttons    SigMapPME = new QSignalMapper(this);    connect(SigMapPME, SIGNAL(mapped(int)), this, SLOT(OptionHandlePME(int)));    SigMapPME->setMapping(pme1, 1);    SigMapPME->setMapping(pme2, 2);    connect(pme1, SIGNAL(clicked()), SigMapPME, SLOT(map()));    connect(pme2, SIGNAL(clicked()), SigMapPME, SLOT(map()));
        //Reset/Close Application buttons    QGroupBox *RCGroup = new QGroupBox("Actions");    ButtonReset= new QPushButton("Reset");    ButtonQuit = new QPushButton("Close");    QHBoxLayout *RCBox = new QHBoxLayout;    RCBox->addWidget(ButtonReset);	RCBox->addWidget(ButtonQuit);    RCBox->addStretch(1);    RCGroup->setLayout(RCBox);    connect(ButtonQuit, SIGNAL(clicked()), qApp, SLOT(quit()));    connect(ButtonQuit, SIGNAL(clicked()), this, SLOT(QuitHandle()) );    connect(ButtonReset, SIGNAL(clicked()), this, SLOT(ResetHandle()) );    	//combine buttons groups into one widget    QWidget *CombineWidget = new QWidget;    QGridLayout *CombineGrid = new QGridLayout;    CombineGrid->addWidget(PMDGroup, 0, 0);    CombineGrid->addWidget(PMEGroup, 1, 0);
    CombineGrid->addWidget(RCGroup, 3, 1);    CombineWidget->setLayout(CombineGrid);
    setCentralWidget(CombineWidget);    setWindowTitle("Options Screen");    resize(480,320);}
void GUI::runQtGUI(int argc,char *argv[]) { 	QPointer app;	QPointer winmain;
	app = new QApplication(argc, argv);	winmain = new MainWindow;	qApp->setQuitOnLastWindowClosed(true);	winmain->show();	app->exec();}

</iostream>

This just sets up a basic radio button option setup, which are then used to adjust some global variables which I then constantly update and display in the other thread in Main to make sure they are updated properly. These globals are also used in the main part of the code to which this is added to actually adjust certain parameters (but I did not include that code seeing as how it is not important).

Also included are my global.cpp and MainWindow.h files:

Source code

1
2
#include "globals.h"#include #include #include #include #include 
//set default values for all global variablesint PMDetector=1;int PMExtractor=1;int SMAlgVar=1;int ASGVar=1;int GBTVar=2;int CRVar=3;int GRVar=3;int HVVar=2;int resetnow = 0;int quitnow = 0;DWORD runQtGUIId;DWORD runProgId;
</iostream>


Source code

1
2
3
4
5
6
7
8
9
10
#ifndef MAINWINDOW_H#define MAINWINDOW_H
#include "globals.h"#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 
namespace GUI {
	class MainWindow : public QMainWindow	{		Q_OBJECT
	public:		explicit MainWindow(QWidget *parent = 0);
	public slots:		void ResetHandle();		void QuitHandle();		void OptionHandlePMD(int buttonIdPMD);		void OptionHandlePME(int buttonIdPME);

	private:		QPushButton *ButtonReset;		QPushButton *ButtonQuit;		QSignalMapper *SigMapPMD;		QSignalMapper *SigMapPME;
	};	void extern runQtGUI(int argc, char *argv[]);}
#endif // MAINWINDOW_H


So there you have it. As long as you copy and pass argc and argv through the WINAPI run thread, you can run a QMainWindow outside of your Main.cpp file and thus easily add a menu to existing code. Again I am aware this is not accepted as 'good' practice, however it sometimes becomes neccesary.

Also the code editor doesnt want to maintain any formatting so I realize the code is difficult to read, but copy and paste into your own editor and it should work.

2

Wednesday, June 27th 2012, 5:45pm

copy / paste this to somewhere else is not going to help

Quoted

#include #include #include #include #include #include #include
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

Wednesday, June 27th 2012, 5:52pm

I also dont see you gain much from this - you could just make normal qt app in main, and push the other app into a thread.
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.

4

Wednesday, June 27th 2012, 6:52pm

Yeah I'm sorry I'm not sure what happened when I put my code in the editor.
Anyways, I believe what I gain is that the rest of the normal code can run without waiting or slowing down for the QT menu.
However, I am not sure what you mean by pushing the app into a thread, how would one do that?

5

Wednesday, June 27th 2012, 9:22pm

you already are, aren't you?

Source code

1
2
3
4
5
6
7
8
9
10
11
int main(int rargc, char *rargv[]){	//copy of argc and argv to pass to QMain	argc=rargc;	argv=rargv;
  CreateThread(NULL,0,runQtGUI,0,0,&runQtGUIId);
  CreateThread(NULL,0,runProg,0,0,&runProgId);
  while(true){
	 if(quitnow == 1){
	  break;
	} 
  }
  std::exit(0);
  return 0;
}
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.

This post has been edited 1 times, last edit by "Amleto" (Jun 28th 2012, 1:04pm)


6

Monday, July 9th 2012, 8:44pm

Okay I see what you mean. Thanks Amleto.