ActiveX et délégué QComboBox
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 besoin ;) Merci d'avance à tous ceux qui pourront m'aider.
Mon code source :
main.cpp
Code:
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
Code:
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 |
uitest_activex.cpp
Code:
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()
{
} |
comboboxdelegate.h
Code:
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 |
ocomboboxdelegate.cpp
Code:
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.h
Code:
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 |
uitest_axcomponent.cpp
Code:
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}") |