PDA

View Full Version : Some questions about qdebug, a custom debug and const approach



tonnot
5th May 2011, 11:42
I have a lot of questions about Qdebug and a way to have control on the messages emited by my progam.


Does it make sense to create an instance of qdebug ? and If yes, how can I create it ?
Can I say it 'Send the messages to this listbox' ?


I have my own debug class, (in order to save the messages in a log file, send them to a listbox, etc ) that use :

mydebug & mydebug('type' value) {
code....
return *this}


I use it in this way:
mydebug()<<"hello"<<variable<<" is "<< "";
It works fine.

Ok, to show or send the message stored (into a string ) I have to use <<""; at the end, because it is the only way to know that the user has ended to send data.
I dont know how Qdebug can do it . For example
qDebug()<<"hello"; ->>> sends "hello" to the application output of QtCreator.
qDebug()<<"hello"<<" peter"; ->>> sends "hello peter" to the application output of QtCreator.
Is there some magical way to do ' Hey , wait, because you are receiving more data' and ' Hey, the ";" is reached'
In other words, I'd like to know when I am receive some << data and when I have no more <<.

And a last question, about using it inside const functions.
I create a public mydebug object to use in several places in my class.

Mydebug mydebug; ......
mydebug<<"data";

Ok, I have errors related to constness (... discard cualifiers....)
( I imagine that this is becasue mydebug functions returns references to itself)
However I can use mydebug()<<"data";
Any way to avoid this ?

I understand that are many questions, can anybody help me ? Some ideas?
Thanks.

high_flyer
5th May 2011, 13:30
Is there some magical way to do ' Hey , wait, because you are receiving more data' and ' Hey, the ";" is reached'
In other words, I'd like to know when I am receive some << data and when I have no more <<.
No magic.
Your Mydebug class defines the operator<<(X);
As long as the type returned by the operator also defines the operator<<(Y), and you use type Y, the operators are just called one after the other:


mydebug()<<"hello"<<variable<<" is "<< ""; //here you use Mydebug::operator<<(QString), then Mydebug::operator(<variable type>), again Mydebug::operator<<(QString) and Mydebug::operator<<(QString).
//If Mydebug class (or classes it derives from) would not implement any of the operators, you would get a compile error.

mcosta
5th May 2011, 13:37
I suggest you to use QtGlobal::qInstallMsgHandler() to install a custom message handler that sends messages to your ListBox

tonnot
5th May 2011, 14:18
Thanks high_flyer (but I dont understand you)
This is my function (for strings):


W_debug& W_debug::operator << (const char * data) {
if (strcmp (data,"")==0)
{ switch (log_file_mode)
{
case 0:
qDebug()<<QString().fromStdString(os.str());
break;
case 1:
log_file->write(os.str());
break;
case 2:
my_window->add(os.str()); // another custom class
break;
}
os.clear(); os.str("");
}
else
{ os<<data; return *this; } // os is a std::stream
}



As you can see I use "" detection to resolve that the user has ended the call.
If not, I cannot to have more than one message per line.
(because, regardless the 'log_mode' method I use, every << will emit the result )
So the question are unresolved, (or I dont understand your explanation) :
If I have w_debug()<<"a word"<< data1<<"a word"<< data2;
How can I know the end of << feeding .,

Thanks


Mcosta : thanks, but I need more control over the messages and QtGlobal::qInstallMsgHandler() perhaps is useful, but I want to develop my own 'w_debug'.

high_flyer
5th May 2011, 15:08
but I dont understand you
I think so too :)
Your code is dangerous, because it assumes the caller of your operator is giving you an array which has "" at the end, I am not even talking about you not checking for a valid pointer 'data', but that is another issue.

Why don't use std::string or QString as input type?
It will make your code safer, and syntactically easier.


How can I know the end of << feeding
I answered that in my previous post.
You don't need to know.
Each operator<<() call takes one argument, and returns a value of some type which you call operator<<() again.
The call ends when all the object instances called their operator<<().

This line:

w_debug()<<"a word"<< data1<<"a word"<< data2;
Is the same as:


w_debug()<<"a word"; //return instance ofw _debug() on which the next call is done
w_debug()<<data1; //return instance of w_debug() on which the next call is done
w_debug()<<"a word";//return instance of w_debug() on which the next call is done
w_debug()<<data2;

tonnot
5th May 2011, 16:10
Excuse me if I am insistent but.
If you call

w_debug()<<"a word ";
w_debug()<<data1;
You have :
a word
33
if I call :

w_debug()<<"a word "<<data1;
You have :
a word
33

And....what I want is :
a word 33

If I have :
W_debug W_debug::operator << (const char * data) {
log_file->write(data);
}
Each time i call << I have data out. So If I want to have more than 1 '<<' at the same line I must to write

W_debug & W_debug::operator << (const char * data) {
log_file->write(data);
return *this;
}

But in this case the line :

w_debug()<<"a word "<<data1;
Produces :
a word
33

Instead of
a word 33

So only it has occurred to me to have a stream object to feed it and when I have a "" data then I can consider that I can send trhe message to the log, to the listbox, or any place.

I hope now you can to understand my problem.
I dont know if it is because my english or what ....

high_flyer
5th May 2011, 16:30
I hope now you can to understand my problem.
It looks to me your problem is in understanding how the operators work in C++, or perhaps int to string conversion?, I am not sure, maybe both?


And....what I want is :
a word 33
Do you want "a ward 33" (everything as a string)?
Then you need to convert your value to string.
If its an int, then you can use:


QByteArray ba = QString::number(data1).toAscii();
const char *pStrData = ba.data();
w_debug()<<"a word "<<pStrData;

for example

But the right way would be to use safe types (which you completely ignored in my post) - why don't you just use QString or at least std::string?

tonnot
5th May 2011, 17:48
Ufff.
Thanks for your patience....
I already have a int to string converter , the std::stringstream does the work.
I use this stringstream to store the elements I want to show later (to a file, to a listbox, to QtCreator application output, etc. )
I have << operator for every type (including QString), so when I call W_debug()<< 33; I store the data into my stringstream.

W_debug & operator << (const QString data) ;
W_debug & operator << (const std::string data);
W_debug & operator << (const char data) ;
W_debug & operator << (const char * data) ;
.....

I have to use const char * data to accept <<"hello" .

If I implement an ' output'(to file, to listbox,etc) on every << , w_debug()<<"1"<<"2"<<"3"; will gives me 3 lines and I want 1.
To avoid this, my idea is to store the information into the stringstream while I have << << << and output when I finish the calls to W_debug.
Now, the 'magic' is how can I know when a '<<' are the last ?

I hope you understand me now and thanks again.

high_flyer
6th May 2011, 08:42
will gives me 3 lines and I want 1.
So just remove the '\n' from the resulting string, or replace it with a space or what ever other charachter just before you want to log it.

tonnot
6th May 2011, 09:35
Thanks high_flyer.
A stringstream has /n ? If yes, the problem can solved...

But then I have another problem,
w_debug()<<"1"<<"2"<<"3"; and
w_debug()<<"4"<<"5"<<"6";
gives me :
123456
and I'd want
123
456


Perhaps this can hellp :
Cout needs to receive and endl because if not there is no line feed.
cout<<"hello"<<"how are you"<<endl;
But qDebug NOT :
qDebug()<<"hello"<<"how are you";

SO ..... what kind of magic is there in qDebug ?
I only can think that there is an internal 'decector' on sentences of execution code. Becasue if not I dont understand how can be posible.
Thanks

high_flyer
6th May 2011, 09:47
frankly, I have no idea what you are after, and why you make it so complicated.
So far I have seen nothing in what you have posted, that qDebug() does not give you since you only output strings.
Its your job to convert what ever other types to strings, and then you can just feed the strings to qDebug().
You are over complicating a non existing problem (in my view).

gives me :
123456
and I'd want
123
456

Well, then put a line break where you need it!
qDebug() will output any string you give it, so just create the string you want the way you want it.

Perhaps this can hellp :
Cout needs to receive and endl because if not there is no line feed.
cout<<"hello"<<"how are you"<<endl;
But qDebug NOT :
qDebug()<<"hello"<<"how are you";
SO ..... what kind of magic is there in qDebug ?
Thats is true, qDebug() adds a line break after every srting, it not magic, just the way it was conceived.
As the qDebug() docs states:

With this syntax, the function returns a QDebug object that is configured to use the QtDebugMsg message type. It automatically puts a single space between each item, and outputs a newline at the end. It supports many C++ and Qt types.

tonnot
6th May 2011, 09:52
My job is not to convert all to strings ....

As you has written :

.... and outputs a newline at the end.
This is the main question, How qDebug do it ? How it knows that there is an end ?
Thanks

high_flyer
6th May 2011, 09:55
My job is not to convert all to strings
Ok, if you say so.


How qDebug do it ?
It just appends an '\n' to any string it gets as input.

You can look in the qDebug() code to see exactly how.

You might want to read the QDebug docs.

tonnot
6th May 2011, 10:34
Solved.
The way is to do it at destructor.....