QApp and finding the MainWindow in one line
-
Hi,
I am using qApp to access a function in my MainWindow class for Debugging purposes (I have a TextEdit in the MainWindow where the debug output is written). As long as there was only one window, the MainWindow, I could access the MainWindow using "qApp->topLevelWidgets().at(0)". However, with more than one window that does not work any more. Since I want to use my debugging method throughout the application, it would be nice to have a oneliner to access the MainWindow. Or is there another elegant way, maybe a more Qt-like way to access the function from everywhere in the application? (I am quite new to the Qt world, so maybe signals and slots would be helpful here as well, but I haven't fully comprehended the concept yet.)
-
Hi!
For debugging purposes, I'd recommend using "qDebug":http://qt-project.org/doc/qt-4.8/qdebug.html() function, where all output from anywhere in the program is written straight to Qt Creator console (you also redirect it inside inside your application).
If options mentioned above is not an options for you, you'll need to use something global.
You can put QTextEdit pointer in a global variable. From there you can then access it from anywhere. -
This ugly kludge should work:
@ QWidget* m = NULL;
foreach(QWidget *widget, qApp->topLevelWidgets())
if(widget->inherits("QMainWindow"))
{ m = widget; break; }@ -
As a complement to what Jake007 said:
Have a look at "qInstallMsgHandler":http://qt-project.org/doc/qt-4.8/qtglobal.html#qInstallMsgHandlerShort version of an idea:
@
static QTextEdit *debugTextEdit = 0;
void myMessageOutput(QtMsgType type, const char *msg)
{
switch (type) {
case QtDebugMsg:
if (debugTextEdit)
debugTextEdit->append("Debug: " + msg)
break;
}
}int main(int argc, char*argv[])
{
qInstallMsgHandler(myMessageOutput);
QApplication app(argc, argv);
debugTextEdit = new QTextEdit;
//....MainWindow.addDebugWidget(debugTextEdit);
}
@Where addDebugWidget is a function that you implement to add the QTextEdit where you need it.
This way you don't have to search for your QTextEdit in all your code and you can use Qt's debugging facilities. Beware the threading issues that might arise.
If you want something more rock solid, KDAB has a nice logging package in their KDTools, it also provides a widget.
-
Thanks for all your answers!
@Jake007: qDebug is not really an option, unfortunately, at least not for all cases, since I pass some additional arguments (among others, a debug level which I use to only show certain messages during development). But a global pointer to the widget might be something.
@Julien: For my personal taste, this is too long to paste it everywhere I need output to the TextEdit :-) But yes, otherwise I would have chosen something like this to identify the MainWindow.
@SGaist: Thanks for your efforts in providing a code example, I will try something like that probably. But I will need to read the docs (i.e. your link) a bit before :-)
-
Hi,
@SGaist: Finally I ended up transferring all the debug code into its own class/dialog, and now I am passing a pointer to that object around, like you proposed in another thread ( http://qt-project.org/forums/viewthread/30019/ ).
There's no need to have it all in the MainWindow, and it's much more elegant and also shorter now :-)Thanks again to all of you!
-
If you don't go the qInstallMsgHandler way. I would suggest that you use the singleton pattern rather than having a pointer wandering from class to class.
-
I had a look at the Singleton pattern (I never practically used it so far), do you think is it just a more elegant way of solving my problem at hand, or are there any specific shortcomings of passing the pointer around? I am using the object read-only, i.e. I do not change any of its members since it is just repsonsible for debug output, so the only thing I could think of which could be a problem would not apply: That any of the objects that access it could change members and consequently the other (accessing) objects would access an object that potentially has changed in the meantime. However, for a singleton that could also apply from what I read.
-
With the singleton you have a "one point of failure". Having a pointer running around you could very well have it uninitialized and be searching for bugs a long time.
Also, you have to initialize your pointer for each and every class where you want to use it and you need to pass it from somewhere. With the singleton, you only have to use it where you need it,
Personally i'd go the qInstallMsgHandler: you don't have the overhead in your code of an additional class/pointer/singleton, just use qDebug() and its friends like you would in any case, makes the code cleaner
-
Thanks for the insight and your suggestions; i will check the options and how feasible they are for me. At least according to Wikipedia the correct implementation of a Singleton doesn't seem to be foolproof, and maybe it is not worth the effort then for me. I'll see ...
Regarding the qInstallMessageHandler: You write "just use qDebug() and its friends", so if I understand that correctly it means with a message handler I would be tied to using qDebug() (plus qWarning() etc.). The myMessageOutput() function you give in your posting has the same parameters as the Qt docs example you link to. And as I understand it, it probably is limited to these parameters because any additional parameters would have to be passed when calling qDebug() which I cannot imagine how it could work. I would need to pass at least one additional parameter because my function is a debugging plus logging function: I am passing a debug level, which can e.g. be 2 for very detailed information, 1 for "normal" debug information and 0 for messages that also the user of the application (which would mostly be me, but also others) is supposed to see in the release version (hm, that last information probably rules out using qDebug() because that will be inactive in the release version ...).
Thanks for your patience :-)
-
Nothing is ever foolproof, but created carefully it should be pretty resistant :)
Then you can add your own layer over qDebug and its friends that does the leveling (or have a look at KDTools)