PDA

View Full Version : How can I work with QDataWidgetMapper?



ysilent
9th November 2011, 08:24
I work with QDataWidgetMapper, but not happy of it's idea.
The problem is that the widget will submit the change when edit finished.
How edit is finished?

Press Enter or lost focus.

So you will see very weird when you change the selection of combo box, you need press enter, otherwise model will not changed. The same as check box, etc.

I cannot work like this. I think the definition of edit ending is wrong.
When you change the selection of combo box, how you can say the edit is not ending?

Anybody has experience or work around?

I did very tricky that connect the index change of combo box signal to my slot and remove the focus.
Why QT didn't consider the situation and do for the developers? No official solution?

wysota
9th November 2011, 08:43
You can change the submision policy of tje widget mapper. No return pressing is required.

ysilent
10th November 2011, 05:03
You mean


QDataWidgetMapper mapper;
mapper.setSubmitPolicy(QDataWidgetMapper::AutoSubm it);


This?

ChrisW67
10th November 2011, 05:18
With AutoSubmit the focus must move from the changed widget to another to trigger the model update. With text boxes this is not usually an issue since users typically tab or enter when finished entry. With check boxes focus is not lost when you toggle the check although the edit is over from the user's perspective. With a combo box index change a similar situation occurs. If you want the update reflected immediately I don't see any option other than connecting the QCheckBox::stateChanged() or QComboBox::currentIndexChanged() signals to a slot that triggers a manual widget mapper commit (or do the mapping manually).

Perhaps I have missed something obvious.

ysilent
10th November 2011, 05:42
With AutoSubmit the focus must move from the changed widget to another to trigger the model update. With text boxes this is not usually an issue since users typically tab or enter when finished entry. With check boxes focus is not lost when you toggle the check although the edit is over from the user's perspective. With a combo box index change a similar situation occurs. If you want the update reflected immediately I don't see any option other than connecting the QCheckBox::stateChanged() or QComboBox::currentIndexChanged() signals to a slot that triggers a manual widget mapper commit (or do the mapping manually).

Perhaps I have missed something obvious.

Exactly. QT never think about what's the definition of "edit finish" for check box or combo box.
I think there many other widget cannot work with data mapper also. Like radio button, slipper, etc. I didn't try.
It's really a design issue for QT.

ChrisW67
10th November 2011, 06:20
If you start defining "edit finished" as "value changed" like you would want to do for check boxes and combo boxes then you break other widgets like line edits. Line edits can contain intermediate values that are not valid, and you don't want to try to push those to the model while they are still being edited. For the data widget mapper to be widget agnostic you have to choose one way to do it (rather than hard code behaviour by widget type or force each widget to provide some signal for the mapper)... Qt chose the one that you would not have.

ysilent
10th November 2011, 09:28
If you start defining "edit finished" as "value changed" like you would want to do for check boxes and combo boxes then you break other widgets like line edits. Line edits can contain intermediate values that are not valid, and you don't want to try to push those to the model while they are still being edited. For the data widget mapper to be widget agnostic you have to choose one way to do it (rather than hard code behaviour by widget type or force each widget to provide some signal for the mapper)... Qt chose the one that you would not have.

I don't agree with your opinion. As a user of these features, the behavior of combo box and check box is not acceptable.
Whatever reason you have, QT make it more complicate for the developers. I don't care about what's the implement behind, I know so far I must do some coding to fix this. I cannot focus on my application development because of these behavior.
OK, let's go to details. In QComboBoxPrivate, it use line edit to submit model changes. I understand sometimes a combo box value also can be edited. In this case it's good to use line edit. But if the combo box is not editable, it's obviously wrong to use a "line edit" to handle the submit behavior. How difficult to invoke d->lineeditor()->event() when the value changed if combo box cannot be edited? I hope it can be improved.
Now I must create my own combo box classes and change the behavior.

wysota
10th November 2011, 13:36
Exactly. QT never think about what's the definition of "edit finish" for check box or combo box.
I think there many other widget cannot work with data mapper also. Like radio button, slipper, etc. I didn't try.
It's really a design issue for QT.

Imagine a situation when the model is connected to a remote slow data source and each submission is very expensive in terms of time. Now imagine you want to edit a record that has 10 columns and you are not certain what values in the combobox you want or whether a checkbox is supposed to be clicked or not. When you start scrolling through the combobox, you start changing the current item. With what you suggest each change would yield an update of the model which as we said was very expensive. Scrolling through 10-20 items in the combobox would take probably a couple of minutes without any benefit to the user (and then multiply that by 10 columns in the model).

Now, the same way you tab out of the text field, you can tab out of the combobox or checkbox if you want to submit changes after each column. If you don't want that, then just connect appropriate signals of your widgets to the submit slot of the data widget mapper.


Whatever reason you have, QT make it more complicate for the developers. I don't care about what's the implement behind, I know so far I must do some coding to fix this. I cannot focus on my application development because of these behavior.
Beautful... You can't focus on your app because Qt requires you to write one line of code. So get rid of Qt -- you won't have to write that one line of code but you will probably have to write tens of thousands of other lines of code. For me the calculation is pretty simple.


Now I must create my own combo box classes and change the behavior.
No, you just need to connect one signal to one slot. Both are already provided.

ysilent
11th November 2011, 03:12
First, I don't understand you when you say "scrolling the combo box" means "change the selection". Scrolling the drop down list of combo box will not occur index change.
Second, I cannot say I have many experience of GUI development. But I have used Java, Cocoa, HTML/Ajax/PHP, C# to develop GUI. As an expert of QT, you must also have many other language experience. Please tell me, which non-editable combo box must press enter to accept the value change? And you need put your own code for standard behavior?
Third, it's cost me time to custom many widgets in my system. Even in most cases we will create our own widgets in applications, but it's not MUST for other languages.
Last, it's waste time to argue here. You are correct, why must QT?

ChrisW67
11th November 2011, 06:49
The currentIndex() of the combo box is changed as soon as you select something from the drop-down whether it is freely editable or not: just like it has been with every other GUI toolkit I've used. A signal indicating that the user has made a selection is also made instantly. With the check box the checkState() is changed immediately and signal to that effect is issued.

However, your problem is nothing to do with the behaviour of the combo box or the check box. Your issue is with the QDataWidgetMapper and the trigger it uses to commit changes to an underlying model, i.e focus change. The data widget mapper functionality doesn't exist in some GUI toolkits, and where it does exist has a range of different behaviours. The design of Qt has chosen one way to do it, which is particularly suited to straight keyboard data entry tasks, e.g. text tab text tab text tab text enter. If you don't like the way it works then either don't use that mechanism at all or adapt it to your purpose. The latter option requires a couple of lines to connect the relevant *Changed() signal to the mapper submit() slot. You certainly don't need to "create my own combo box classes and change the behavior" unless you are determined to make this harder than it need be.

It might be annoying, but you've wasted much more time complaining about it than it would take to do it.

wysota
11th November 2011, 10:24
I totally agree with Chris.