PDA

View Full Version : Why is QDialog.show() overriding my lineEdit text?



tescrin
18th June 2012, 21:22
Basically, I've subclassed QDoubleSpinBox with my own (also tried QSpinBox) and want to have it *START* as "0.0." I can get everything to work right but when I initialize the value and the code gets to the QDialog's "show()" function, it'll overwrite my text value back to "0.00") (or "0" respectively.) I know it seems odd but I *have* to have it start at "0.0".

As I debugged I found that the value is changed at QDialog's function "show()", (or more directly "setVisible(bool)" since that's what show() calls AFAIK.) I've tried to look through more of the (qt) source code to track the issue but I can't seem to figure out where it's at exactly. Why on earth would setVisible(bool)/show() change my values?!

Currently my only fix is VERY dirty; I had to make a public function that would initialize the value to what I wanted and put it all the way in the QApp's main function *after* show. Please help me write truly object oriented code and get around this. I have no qualms overriding setVisible if this has to be done as long as that's a feasible task.



P.S. Any explanation as to WHY setVisible changes values would also be spectacular...

EDIT: [Actually, it's worth noting that this happens possibly because I used Qt Designer (in the qt creator) to start the project and then "promoted" the widget to my custom one. Everything else works fine, but this is highly desired functionality. It might be that in the generated code the show function calls some initialization functions, but i don't see why it would.]
Nevermind this idea, I've gone through the generated code of the UI file and it does not reference the show or setVisible function.

wysota
18th June 2012, 21:37
The answer is pretty simple -- there is no point interpreting any values before the value is actually needed. And it is needed for the first time when you show the widget, so when the widget gets shown, the value stored in the widget gets set as the text of the line edit. If you want to customize some value then either reimplement QDoubleSpinBox::textFromValue() or use QAbstractSpinBox::specialValueText property.

tescrin
18th June 2012, 21:53
:s, do they note that in the documentation of that function? That's not OOP at all, and quite bothersome IMO.

But I'll be done whining lol; I've added:

setSpecialValueText("0.0"); to the constructor and added the test functions


QString textSpinBox::textFromValue()
{
return thisLineEdit->text();
}

double textSpinBox::valueFromText()
{
return thisLineEdit->text().toDouble();
}


but it still shows "0.00" as it's default value.

Would you know any other functions that might be called to mess with the value on start up? (Thank you for the help btw)

EDIT: For clarification "thisLineEdit" is a pointer I added to the class to point to the lineEdit's text. While it's not *really* necessary it's a convenience for now. Also, this lineEdit's regExp is defaulted at the moment until I can get this working, however, I will note that making the regExp something that a 0.00 would be illegal in didn't keep it from setting it to that IIRC. I'd have to check against.

wysota
18th June 2012, 22:07
:s, do they note that in the documentation of that function? That's not OOP at all, and quite bothersome IMO.

Hmm? What exactly? What is not OOP here?


but it still shows "0.00" as it's default value.
I don't see why it wouldn't since you overloaded those methods instead of overriding them so your methods are never called.

tescrin
18th June 2012, 22:25
Hm, I'm screwing up something here, but I think I got it figured out. Thank you for pointing out my should've-been-obvious-to-me overloading. I didn't pay enough attention :s. Also, thank you for pointing out which function it was calling; I was scrawling through the source trying to find what was being called; and with little success.

To continue the side discussion; an object should maintain state. If I set the objects value, something that should be akin to switch a flag shouldn't be changing any values but the flag. I.E. setVisible should set the property "Visible" (or similar) and it's parent object should worry about whether or not to display it. That is all. (It would probably do this by running a thread that's checking the visible state of it's children or something.)

Instead this violates "Encapsulation" IMO, because it mutates a value that I've not only set to another value, but it mutates it despite me limiting access to it. I'd love to continue discussing this; so I'll keep an eye on the thread.

Thanks again!

wysota
18th June 2012, 22:40
If I set the objects value, something that should be akin to switch a flag shouldn't be changing any values but the flag.
You shouldn't be setting that value at all. The value of the widget is QDoubleSpinBox::value and not QLineEdit::text thus QDoubleSpinBox doesn't care about favouring your custom text over its own functionality. Perfectly OOP for me. If anyone breaks encapsulation, it is you by manipulating a subobject instead of the main object. QDoubleSpinBox guarantees you that the line edit always shows the value of the spin box. If you try to work around it the wrong way, don't blame QDoubleSpinBox. If the widget is shown and you set some absurd text on the line edit, it will be reverted to the spinbox value. Why would the widget behave differently when it is not being shown?

tescrin
19th June 2012, 16:55
Actually, until I messed with it a bit (later) and then combined that with your reply I didn't realize it was working like that. It does make sense I guess. I was thinking of any int value as merely a... means to deal with spinning and such more easily and not the... "head honcho" of the information. It made sense to me that the display value would be the real information and that anything that changed it would refer to *it* for accuracy.

In this case then it IS still OOP (I'm now agreeing with you) because it's not resetting a value, it's... dynamically acquiring it. Had I known that I bet I could've just overridden the double they use to just display with a single decimal digit eh? (If you come back around I'd really like to know actually.)

I guess this means I'll re-implement this in the real version so it's not working against itself. Thank you for the information!


p.s. As another question, did you learn all this from the source code or are you just intimately familiar or..? I ask because I was really digging through the source trying to figure out why setVisible was doing this. I got into some code I couldn't hardly recognize (something recursively calling d_func() to it's child members, and documentation on that is little as it seems that's a Qt programmer tool and not something the users should be using [from what I gathered].)

wysota
19th June 2012, 20:57
Had I known that I bet I could've just overridden the double they use to just display with a single decimal digit eh? (If you come back around I'd really like to know actually.)
What is displayed is totally controlled by what textFromValue() returns.


p.s. As another question, did you learn all this from the source code or are you just intimately familiar or..?
A lot of experience with how Qt works and how Qt developers think and a lot of time spent on reading the source code of Qt and implementing my own widgets (including spinboxes -- have a look at the link in my signature).