Salut !
Je voudrais développer un ActiveX utilisant un QTableWidget possédant des delegates de type QComboBox.
Le QTableWidget que j'ai développé fonctionne parfaitement si je l'intègre dans une QMainWindow mais son comportement change dès que je l'intègre dans mon ActiveX. Lorsque je sélectionne un des choix d'une des QComboBox, celle-ci ne reçoit pas le focus et l'évènement itemChanged du QTableWidget n'est pas appelé lorsque je clique sur une autre cellule de la table. Lorsque je force le focus en faisant clic droit sur la QComboBox et que je clique sur une autre cellule de la table, l'évènement est cette fois-ci bien appelé.
J'ai trouvé un début de solution en connectant le signal currentIndexChanged(int) sur un slot de mon delegate pour émettre les signaux commitData() et closeEditor(). Cela résoud le problème si j'utilise la souris pour sélectionner le choix dans la QComboBox mais pas si j'utilise le clavier. En effet, je perd le focus à chaque fois que je fais défiler les choix avec les flèches haut et bas.
Je voudrais savoir s'il s'agit d'un bug de Qt ou si j'ai oublié quelque chose et s'il existe une solution.
J'ai développé une version simplifiée de mon projet sous VS 2008 qui reproduit le problème :
https://rapidshare.com/files/5517533...st_ActiveX.zip
Le QTableWidget du haut est intégré dans un ActiveX et possède le problème décrit ci-dessus. Celui du bas est dans une QFrame et fonctionne comme je le souhaite.
N'hésitez pas à le tester et à me demander des précisions si vous en avez besoinMerci d'avance à tous ceux qui pourront m'aider.
Mon code source :
main.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 #include "uitest_activex.h" #include <QtGui/QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); UITest_ActiveX w; w.show(); return a.exec(); }
uitest_activex.h
uitest_activex.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #ifndef UITEST_ACTIVEX_H #define UITEST_ACTIVEX_H #include <QtGui/QMainWindow> #include "ui_uitest_activex.h" class UITest_ActiveX : public QMainWindow { public: UITest_ActiveX(QWidget *parent = 0, Qt::WFlags flags = 0); ~UITest_ActiveX(); private: Ui::UITest_ActiveXClass ui; }; #endif // UITEST_ACTIVEX_H
comboboxdelegate.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 #include "uitest_activex.h" #include <QtGui/QVBoxLayout> #include <ActiveQt/QAxWidget> #include <QTGui/QTableWidget> #include "..\UITest_AxComponent\comboboxdelegate.h" UITest_ActiveX::UITest_ActiveX(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { ui.setupUi(this); QFrame* inv_frame = new QFrame(); inv_frame->resize(1200, 1200); inv_frame->setMinimumSize(QSize(800, 600)); QVBoxLayout* lnv_vertical_layout = new QVBoxLayout(inv_frame); //TEST1 : in an ActiveX Component QAxWidget* inv_ax_helpdesk = new QAxWidget(inv_frame) ; inv_ax_helpdesk->setControl( "{5E3FC5ED-FBA6-47AE-B1A3-31567AF9C2F3}" ) ; inv_ax_helpdesk->setObjectName( QString::fromUtf8( "inv_ax_helpdesk" ) ) ; inv_ax_helpdesk->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); lnv_vertical_layout->addWidget(inv_ax_helpdesk); //END TEST 1 //TEST2 : not in an ActiveX Component QTableWidget* lnv_table_widget = new QTableWidget(); lnv_table_widget->setRowCount(10); lnv_table_widget->setColumnCount(2); lnv_vertical_layout->addWidget( lnv_table_widget ); for(int li_column = 0; li_column < 2; ++li_column) { for(int li_row = 0; li_row < 10; ++li_row) { lnv_table_widget->setItem(li_row, li_column, new QTableWidgetItem(0)); lnv_table_widget->item(li_row, li_column)->setData(Qt::DisplayRole, 1); } } lnv_table_widget->setItemDelegateForColumn(0, new ComboBoxDelegate()); for(int li_index = 0; li_index < 30; ++li_index) { lnv_table_widget->openPersistentEditor(lnv_table_widget->item(li_index, 0)); } //END TEST 2 this->setCentralWidget(inv_frame); } UITest_ActiveX::~UITest_ActiveX() { }
ocomboboxdelegate.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #ifndef COMBOBOXDELEGATE_H #define COMBOBOXDELEGATE_H #include <QtGui/QStyledItemDelegate.h> #include <QtGui/QComboBox> #include "defines.h" class UITEST_AXCOMPONENT_EXPORT ComboBoxDelegate : public QStyledItemDelegate { Q_OBJECT private: QComboBox* inv_combobox; public: ComboBoxDelegate(QObject* anv_parent = 0); ~ComboBoxDelegate(); QWidget* createEditor(QWidget* auo_parent, const QStyleOptionViewItem& anv_option, const QModelIndex& anv_modelIndex) const; void setEditorData(QWidget* auo_editor, const QModelIndex& anv_modelIndex) const; void setModelData(QWidget* auo_editor, QAbstractItemModel* anv_model, const QModelIndex& anv_modelIndex) const; private slots: void commitAndCloseEditor(); }; #endif
uitest_axcomponent.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 #include <QtGui/QtGui> #include "comboboxdelegate.h" ComboBoxDelegate::ComboBoxDelegate(QObject* anv_parent) : QStyledItemDelegate(anv_parent) { inv_combobox = 0; } ComboBoxDelegate::~ComboBoxDelegate() { if(inv_combobox != 0) { delete inv_combobox; } } QWidget* ComboBoxDelegate::createEditor(QWidget* anv_parent, const QStyleOptionViewItem& anv_option , const QModelIndex& anv_model_index) const { QComboBox* lw_new_editor = new QComboBox(anv_parent); lw_new_editor->autoFillBackground(); lw_new_editor->addItem("Choice0", 0); lw_new_editor->addItem("Choice1", 1); lw_new_editor->addItem("Choice2", 2); //QObject::connect(lw_new_editor, SIGNAL(currentIndexChanged(int)), this, SLOT(commitAndCloseEditor()) ); return lw_new_editor; } void ComboBoxDelegate::setEditorData(QWidget* anv_editor, const QModelIndex& anv_model_index) const { QComboBox* lnv_combobox = static_cast<QComboBox*>(anv_editor); QVariant lv_data = anv_model_index.model()->data(anv_model_index, Qt::DisplayRole); int li_index = lnv_combobox->findData(lv_data, Qt::UserRole); lnv_combobox->setCurrentIndex(li_index); } void ComboBoxDelegate::setModelData(QWidget* anv_editor, QAbstractItemModel* anv_model, const QModelIndex& anv_model_index) const { QComboBox* lnv_combobox = static_cast<QComboBox*>(anv_editor); int li_index = lnv_combobox->currentIndex(); //récupération des data dans la ComboBox QVariant lnv_data = lnv_combobox->itemData(li_index, Qt::UserRole); //recopie des data dans le modèle de données anv_model->setData(anv_model_index, lnv_data, Qt::DisplayRole); QModelIndex lnv_model_index = anv_model->index(anv_model_index.row(), anv_model_index.column() + 1); anv_model->setData(lnv_model_index, lnv_data, Qt::DisplayRole); } void ComboBoxDelegate::commitAndCloseEditor() { qDebug() << "ComboBoxDelegate::commitAndCloseEditor"; QComboBox* editor = qobject_cast<QComboBox*>(sender()); emit commitData(editor); emit closeEditor(editor); }
uitest_axcomponent.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #ifndef UITEST_AXCOMPONENT_H #define UITEST_AXCOMPONENT_H #include <QtGui/QWidget> #include <ActiveQt/QAxBindable> #include "ui_uitest_axcomponent.h" class UITest_AxComponent : public QWidget, public QAxBindable { Q_OBJECT public: UITest_AxComponent(QWidget *parent = 0); private: Ui::UITest_AxComponentClass ui; }; #endif // UITEST_AXCOMPONENT_H
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #include "uitest_axcomponent.h" #include <ActiveQt/QAxFactory> #include <QtGui/QTableWidget> #include <QtGui/QVBoxLayout> #include "comboboxdelegate.h" UITest_AxComponent::UITest_AxComponent(QWidget *parent) : QWidget(parent) { ui.setupUi(this); QVBoxLayout* lnv_vertical_layout = new QVBoxLayout(this); QTableWidget* lnv_table_widget = new QTableWidget(); lnv_table_widget->setRowCount(10); lnv_table_widget->setColumnCount(2); lnv_vertical_layout->addWidget( lnv_table_widget ); for(int li_column = 0; li_column < 2; ++li_column) { for(int li_row = 0; li_row < 10; ++li_row) { lnv_table_widget->setItem(li_row, li_column, new QTableWidgetItem(0)); lnv_table_widget->item(li_row, li_column)->setData(Qt::DisplayRole, 1); } } lnv_table_widget->setItemDelegateForColumn(0, new ComboBoxDelegate()); for(int li_index = 0; li_index < 30; ++li_index) { lnv_table_widget->openPersistentEditor(lnv_table_widget->item(li_index, 0)); } } QAXFACTORY_DEFAULT(UITest_AxComponent, "{5E3FC5ED-FBA6-47AE-B1A3-31567AF9C2F3}", "{129C2AEF-95FF-41CD-933A-BB6797C15EA7}", "{D649E3DF-8A75-4760-BE24-C95099DA12E3}", "{95A80282-D524-472A-893B-34362AB50097}", "{5925E413-B343-47BA-9C8A-9D63E0F06F2C}")
Partager