ActiveX and QComboBox delegate
Hi !
I'm developping an ActiveX component using a QTableWidget with QComboBox delegates.
The QTableWidget works perfectly when I use it in a QMainWindow directly but its behaviour changes once embedded in an ActiveX.
When I select a choice in one of the QComboBox, the focus is not set on the widget and the event itemChanged is not called on QTableWidget when I select an other cell of the table. When I force the focus on the QComboBox by right clicking on it, the event is called when I select an other cell.
I found a solution by connecting the signal currentIndexChanged(int) to a slot which emit the signals commitData() and closeEditor(). It solves the problem when using the mouse to select the choice but not when using the keyboard. The focus is lost whenever I press the down arrow.
I'd like to know if it is a known bug of Qt or if I missed something and if there is a good solution to solve it.
I made a simple project on VS2008 which reproduce this problem.
https://rapidshare.com/files/5517533...st_ActiveX.zip
The top QTableWidget is in an ActiveX and has the problem. The bottom QTableWidget is in a frame and works as I want.
Don't hesitate to test it and ask me more details.
Thanks.
Here is my source code :
main.cpp
Code:
#include "uitest_activex.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
UITest_ActiveX w;
w.show();
return a.exec();
}
uitest_activex.h
Code:
#ifndef UITEST_ACTIVEX_H
#define UITEST_ACTIVEX_H
#include <QtGui/QMainWindow>
#include "ui_uitest_activex.h"
{
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:
#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
){
ui.setupUi(this);
inv_frame->resize(1200, 1200);
inv_frame
->setMinimumSize
(QSize(800,
600));
//TEST1 : in an ActiveX Component
inv_ax_helpdesk->setControl( "{5E3FC5ED-FBA6-47AE-B1A3-31567AF9C2F3}" ) ;
inv_ax_helpdesk
->setObjectName
( QString::fromUtf8( "inv_ax_helpdesk" ) ) ;
lnv_vertical_layout->addWidget(inv_ax_helpdesk);
//END TEST 1
//TEST2 : not in an ActiveX Component
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->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:
#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:
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;
private slots:
void commitAndCloseEditor();
};
#endif
ocomboboxdelegate.cpp
Code:
#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 {
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:
#ifndef UITEST_AXCOMPONENT_H
#define UITEST_AXCOMPONENT_H
#include <QtGui/QWidget>
#include <ActiveQt/QAxBindable>
#include "ui_uitest_axcomponent.h"
{
Q_OBJECT
public:
UITest_AxComponent
(QWidget *parent
= 0);
private:
Ui::UITest_AxComponentClass ui;
};
#endif // UITEST_AXCOMPONENT_H
uitest_axcomponent.cpp
Code:
#include "uitest_axcomponent.h"
#include <ActiveQt/QAxFactory>
#include <QtGui/QTableWidget>
#include <QtGui/QVBoxLayout>
#include "comboboxdelegate.h"
UITest_AxComponent
::UITest_AxComponent(QWidget *parent
){
ui.setupUi(this);
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->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}")
Re: ActiveX and QComboBox delegate
Re: ActiveX and QComboBox delegate
should I report it as a bug ?
Re: ActiveX and QComboBox delegate
Please, I still need help !