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
#include "uitest_activex.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
UITest_ActiveX w;
w.show();
return a.exec();
}
#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();
}
To copy to clipboard, switch view to plain text mode
uitest_activex.h
#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
#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
To copy to clipboard, switch view to plain text mode
uitest_activex.cpp
#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()
{
}
#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()
{
}
To copy to clipboard, switch view to plain text mode
comboboxdelegate.h
#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
#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
To copy to clipboard, switch view to plain text mode
ocomboboxdelegate.cpp
#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);
}
#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);
}
To copy to clipboard, switch view to plain text mode
uitest_axcomponent.h
#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
#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
To copy to clipboard, switch view to plain text mode
uitest_axcomponent.cpp
#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}")
#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}")
To copy to clipboard, switch view to plain text mode
Bookmarks