PDA

View Full Version : QItemDelegate Align



aekilic
24th March 2009, 09:16
Dear All

We have a problem,


MyDoubleSpinBox2 *editor = new MyDoubleSpinBox2(parent);

QToolButton *tool;
tool = new QToolButton(editor);
tool->setText("...");

return editor;


When we do this we get the tool button on left, how we could get the button on right?

spirit
24th March 2009, 09:20
try to use QWidget::setGeometry or QWidget::move. but anyway when editor is being resized you need to move your tool button to new position. so, you can process QResizeEvent of your editor and update tool button position. another way it's to put your editor and tool button in layout.

wysota
24th March 2009, 09:21
Move it there using QWidget API.

aekilic
24th March 2009, 09:26
can we do it with

bool QLayout::setAlignment ( QWidget * w, Qt::Alignment alignment )???

spirit
24th March 2009, 09:35
there is not necessary of using this method. all what you need it's to put all widget in right order. you need to use QHBoxLayout.
but in this case your tool button will not be located on your editor, but it will be located on ther right of your spindox.

aekilic
24th March 2009, 10:19
I was not able to use QHBoxLayout,

When I use


MyDoubleSpinBox2 *editor = new MyDoubleSpinBox2(parent);

QToolButton *tool;
tool = new QToolButton();
tool->setText("...");

QHBoxLayout layout;
layout.addWidget(editor);
layout.addWidget(tool);


I could not see tool button

spirit
24th March 2009, 10:31
wrong code. try this


QWdiget *w = new QWidget(parent);
MyDoubleSpinBox2 *editor = new MyDoubleSpinBox2();

QToolButton *tool = new QToolButton();
tool->setText("...");

QHBoxLayout *layout = new QHBoxLayout(w);
layout->addWidget(editor);
layout->addWidget(tool);

return w;

aekilic
24th March 2009, 10:49
Dear spirit

In this way, tool button located in the spin not near

spirit
24th March 2009, 10:52
can show a screenshot?

aekilic
24th March 2009, 10:57
in the attach

spirit
24th March 2009, 11:02
this may work


...
QWidget *w = new QWidget(parent);
QSpinBox *sp = new QSpinBox();
QToolButton *tb = new QToolButton();
QHBoxLayout *hbl = new QHBoxLayout(w);
sp->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
tb->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
w->setFocusProxy(sp);
hbl->setMargin(0);
hbl->setSpacing(0);

hbl->addWidget(sp);
hbl->addWidget(tb);

return w;
...

void ItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index);
editor->setGeometry(option.rect);
}

code updated.

aekilic
24th March 2009, 11:26
this works great but we have a problem with



void ProformaDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QWidget *w = static_cast<MyDoubleSpinBox2*>(editor);

MyDoubleSpinBox2 *spinBox = static_cast<MyDoubleSpinBox2*>(w);
spinBox->setValue(turkish.toDouble(index.model()->data(index, Qt::EditRole).toString().remove(totalParaBirimi, Qt::CaseInsensitive)));
spinBox->selectAll();
}


Can we do it like this?

spirit
24th March 2009, 11:28
no, you can't do this. create your own widget which will return data.

aekilic
24th March 2009, 11:47
himmmm

how can I do it then?

spirit
24th March 2009, 11:52
the simpliest way


class MyComplexEditor: public QWidget
{
Q_OBJECT

public:
MyComplexEditor(QWidget *parent = 0) : QWidget(parent)
{
m_spinBox = new QSpinBox();
m_toolButton = new QToolButton();
QHBoxLayout *hbl = new QHBoxLayout(this);
m_spinBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_toolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
setFocusProxy(m_spinBox);
hbl->setMargin(0);
hbl->setSpacing(0);

hbl->addWidget(m_spinBox);
hbl->addWidget(m_toolButton);
}

QSpinBox *spinBox() const { return m_spinBox; }
QToolButton *toolButton() const { return m_toolButton; }

private:
QSpinBox *m_spinBox;
QToolButton *m_toolButton;
};

...
void MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return new MyComplexEditor(parent);
}

void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
MyComplexEditor *mce = qobject_cast<MyComplexEditor *>(editor);
if (!mce)
return;
mce->spinBox()->setValue(turkish.toDouble(index.model()->data(index, Qt::EditRole).toString().remove(totalParaBirimi, Qt::CaseInsensitive)));
mce->spinBox()->selectAll();
}
}

nothing complex, right? ;)

aekilic
24th March 2009, 15:05
Thank you very much problem solved, but was not complex:)

aekilic
24th March 2009, 18:36
I got one more question for the tool botton

I create a action, and add to toolbotton.



QAction *enDusukAlis = new QAction(QString::fromUtf8("En DüşÃ¼k Alış Fiyatı"), w->toolButton());
connect(enDusukAlis, SIGNAL(activated()), w->toolButton(), SLOT(slotenDusukAlis()));
w->toolButton()->addAction(enDusukAlis);


this slotenDusukAlis has to find something and put a number in a spin. But I was not able to work signal and slot can anybody help?

spirit
24th March 2009, 18:42
looks strange


connect(enDusukAlis, SIGNAL(activated()), w->toolButton(), SLOT(slotenDusukAlis()));

QToolButton has not such slot slotenDusukAlis.

aekilic
25th March 2009, 08:15
Dear All

What I need to do is,

I have QAction's on the QToolMenu,

Like
Best Price '10'
Low Price '8'

What I need to do is, after user select Best Price '10' I need to put 10 to the spin...

Am I able to explain?

Lykurg
25th March 2009, 08:30
a) use QRegExp to extract the number of the displayed text
or better
b) use QAction::setData() to store your number while generating the QActions

use the QToolButton::triggered ( QAction * action ) signal.

aekilic
25th March 2009, 08:38
What I use is,



QAction *enDusukAlis = new QAction(QString::fromUtf8("En DüşÃ¼k Alış Fiyatı"), w->toolButton());
connect(enDusukAlis, SIGNAL(activated()), this, SLOT(slotenDusukAlis()));
w->toolButton()->addAction(enDusukAlis);


But the signal doesnt work

Lykurg
25th March 2009, 08:50
A QAction has only the signals:
void changed ()
void hovered ()
void toggled ( bool checked )
void triggered ( bool checked = false )
void destroyed ( QObject * obj = 0 )

No activated!

spirit
25th March 2009, 08:50
yup, Qt Assistant -- rocks!

aekilic
25th March 2009, 08:58
yup, Qt Assistant -- rocks!

yes, it really rocks!

For the setData how can I use it then?

aekilic
25th March 2009, 09:15
.....
QAction *enDusukSatis = new QAction(QString::fromUtf8("En DüşÃ¼k Satış Fiyatı"), w->toolButton());
connect(enDusukSatis, SIGNAL(triggered()), this, SLOT(test()));
w->toolButton()->addAction(enDusukSatis);
.....
void ProformaDelegate::test()
{
QMessageBox::warning(0, QString::fromUtf8("HATA"),
QString::fromUtf8("İşlemde bir hata oluştu \nLütfen tekrar deneyiniz \nveya \nSistem uzmanına başvurunuz"));

}


But the signal doent work...:(

spirit
25th March 2009, 09:31
everything should work, press and hold a tool button, a popup menu should appear with your action. if you want slot is being called immediately then


connect(w->toolButton(), SIGNAL(clicked()), this, SLOT(test()));

aekilic
25th March 2009, 09:52
Dear Spirit



connect(w->toolButton(), SIGNAL(clicked()), this, SLOT(test()));


also doesnt work :(

Lykurg
25th March 2009, 09:54
Then show us your (whole) code. Maybe Q_OBJECT forgotten? Do you get a warning?

spirit
25th March 2009, 09:55
what does this operation show in console?


qDebug() << connect(w->toolButton(), SIGNAL(clicked()), this, SLOT(test()));

did you add Q_OBJECT macro in your class declaration.
PS. I've just tested both of these approaches and they work fine for me.

aekilic
25th March 2009, 10:18
h.h



class ProformaDelegate : public QItemDelegate
{
Q_OBJECT

QString totalParaBirimi;
public:
ProformaDelegate(QObject *parent = 0, const QString &paraBirimi = QString::null);

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;

void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;

void test();
private:
QWidget *m_handler;

};

class MyComplexEditor: public QWidget
{
Q_OBJECT

public:
MyComplexEditor(QWidget *parent = 0) : QWidget(parent)
{
m_spinBox = new MyDoubleSpinBox2();



m_toolButton = new QToolButton();

QHBoxLayout *hbl = new QHBoxLayout(this);
m_spinBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_toolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
setFocusProxy(m_spinBox);
hbl->setMargin(0);
hbl->setSpacing(0);

hbl->addWidget(m_spinBox);
hbl->addWidget(m_toolButton);
}
void slotenDusukAlis()
{
QMessageBox::warning(0, QString::fromUtf8("HATA"),
QString::fromUtf8("İşlemde bir hata oluştu \nLütfen tekrar deneyiniz \nveya \nSistem uzmanına başvurunuz"));
}
MyDoubleSpinBox2 *spinBox() const { return m_spinBox; }
QToolButton *toolButton() const { return m_toolButton; }

private:
MyDoubleSpinBox2 *m_spinBox;
QToolButton *m_toolButton;
};

#endif


h.cpp



#include "proformaDelegate.h"
#include "libs/Delegate/myDoubleSpinBox.h"


ProformaDelegate::ProformaDelegate(QObject *parent, const QString &paraBirimi): QItemDelegate(parent)
{

}
QString gosteri = "%L1";


QWidget *ProformaDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QLocale::setDefault(QLocale(QLocale::Turkish, QLocale::Turkey));

if(index.column() == 5)
{
MyComplexEditor *w = new MyComplexEditor(parent);

w->spinBox()->setMinimum(0);
w->spinBox()->setMaximum(4000000000);
w->spinBox()->setDecimals(4);
w->spinBox()->setSuffix(" " + totalParaBirimi);
w->spinBox()->setAlignment(Qt::AlignRight);
w->spinBox()->setButtonSymbols(QAbstractSpinBox::NoButtons);
w->spinBox()->selectAll();

w->toolButton()->setText("...");
w->toolButton()->setPopupMode(QToolButton::InstantPopup);


QAction *enDusukSatis = new QAction(QString::fromUtf8("En DüşÃ¼k Satış Fiyatı"), w->toolButton());
connect(enDusukSatis, SIGNAL(trigger()), this, SLOT(test()));
w->toolButton()->addAction(enDusukSatis);


connect(w->toolButton(), SIGNAL(clicked()), this, SLOT(test()));

QAction *enOrtAlis = new QAction(QString::fromUtf8("Ortalama Alış Fiyatı"), w->toolButton());
connect(enOrtAlis, SIGNAL(activated()), w->toolButton(), SLOT(slotenOrtAlis()));
w->toolButton()->addAction(enOrtAlis);

QAction *enOrtSatis = new QAction(QString::fromUtf8("Ortalama Alış Fiyatı"), w->toolButton());
connect(enOrtSatis, SIGNAL(activated()), w->toolButton(), SLOT(slotenOrtSatis()));
w->toolButton()->addAction(enOrtSatis);

QAction *enYuksAlis = new QAction(QString::fromUtf8("En Yüksek Alış Fiyatı"), w->toolButton());
connect(enYuksAlis, SIGNAL(activated()), w->toolButton(), SLOT(slotenYuksAlis()));
w->toolButton()->addAction(enYuksAlis);

QAction *enYuksSatis = new QAction(QString::fromUtf8("En Yüksek Satış Fiyatı"), w->toolButton());
connect(enYuksSatis, SIGNAL(activated()), w->toolButton(), SLOT(slotenYuksSatis()));
w->toolButton()->addAction(enYuksSatis);

QAction *enSonAlis = new QAction(QString::fromUtf8("Son Alış fiyatı"), w->toolButton());
connect(enSonAlis, SIGNAL(activated()), w->toolButton(), SLOT(slotenSonAlis()));
w->toolButton()->addAction(enSonAlis);

QAction *enSonSatis = new QAction(QString::fromUtf8("Son Satış fiyatı"), w->toolButton());
connect(enSonSatis, SIGNAL(activated()), w->toolButton(), SLOT(slotenSonSatis()));
w->toolButton()->addAction(enSonSatis);

/* En DüşÃ¼k Alış Fiyatı
En DüşÃ¼k Satış Fiyatı
Ortalama Alış Fiyatı
Ortalama Satış Fiyatı
En Yüksek Alış Fiyatı
En Yüksek Satış Fiyatı
Son Alış fiyatı
Son Satış fiyatı*/


QSqlQuery markaid_q;
markaid_q.exec("SELECT markaid FROM stokdakiler WHERE stokdakilerid = '" + index.model()->data(index.sibling(index.row(), 2), Qt::StatusTipRole).toString() + "';");
markaid_q.next();

QSqlQuery fiyat_tipleri;
fiyat_tipleri.exec("SELECT id, stokid, markaid, fiyat_tipleri.fiyat_tipi || ' (' || kurcinsi || ') ' || fiyat, fili_fiyat FROM stokdakiler_fiyat "
"LEFT JOIN fiyat_tipleri ON fiyat_tipleri.fiyat_tipi_id = stokdakiler_fiyat.fiyat_tip "
"LEFT JOIN kur ON kur.kurid = stokdakiler_fiyat.kur_id "
"WHERE markaid = '" + markaid_q.value(0).toString() + "' AND "
"stokid = '" + index.model()->data(index.sibling(index.row(), 1), Qt::StatusTipRole).toString() + "';");
int i = 0;
while(fiyat_tipleri.next()){
// QMessageBox::warning(0, QString::fromUtf8("HATA"),
// QString::fromUtf8("İşlemde bir hata oluştu \nLütfen tekrar deneyiniz \nveya \nSistem uzmanına başvurunuz"));
QAction *cutAction = new QAction(fiyat_tipleri.value(3).toString(), w->toolButton());
w->toolButton()->addAction(cutAction);
++i;
// sayi = i;
}


// return new MyComplexEditor(parent);
return w;

}

return 0;
}
void ProformaDelegate::test()
{
QMessageBox::warning(0, QString::fromUtf8("HATA"),
QString::fromUtf8("İşlemde bir hata oluştu \nLütfen tekrar deneyiniz \nveya \nSistem uzmanına başvurunuz"));

}

void ProformaDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index);
editor->setGeometry(option.rect);
}
void ProformaDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QLocale turkish(QLocale::Turkish);

if(index.column() == 5)
{
MyComplexEditor *mce = qobject_cast<MyComplexEditor *>(editor);
if (!mce)
return;
mce->spinBox()->setValue(turkish.toDouble(index.model()->data(index, Qt::EditRole).toString().remove(totalParaBirimi, Qt::CaseInsensitive)));
mce->spinBox()->selectAll();
}
}

void ProformaDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QLocale turkish(QLocale::Turkish);

if(index.column() == 5)
{
MyComplexEditor *mce = static_cast<MyComplexEditor *>(editor);
if (!mce)
return;
model->setData(index, gosteri.arg(mce->spinBox()->value(),0,'f',2) + " " + totalParaBirimi, Qt::DisplayRole);

}

}

spirit
25th March 2009, 10:21
come on void test() it's not a slot :)
do this.


private slots:
void test();

aekilic
25th March 2009, 17:15
Dear Spirit

I put it in

private slots:
void test();

but notting changed

spirit
25th March 2009, 17:24
works perfectly
cpp


QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(option);
Q_UNUSED(index);

MyComplexEditor *mce = new MyComplexEditor(parent);

QAction *enDusukSatis = new QAction("test", mce->toolButton());
connect(enDusukSatis, SIGNAL(triggered()), SLOT(test()));
mce->toolButton()->addAction(enDusukSatis);
//connect(mce->toolButton(), SIGNAL(clicked()), SLOT(test()));

return mce;
}

void ItemDelegate::test()
{
QMessageBox::information(0, tr("information"), tr("test"));
}

void ItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index);
editor->setGeometry(option.rect);
}

h


class MyComplexEditor: public QWidget
{
Q_OBJECT

public:
MyComplexEditor(QWidget *parent = 0) : QWidget(parent)
{
m_spinBox = new QSpinBox();
m_toolButton = new QToolButton();
m_toolButton->setText("...");
QHBoxLayout *hbl = new QHBoxLayout(this);
m_spinBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_toolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
setFocusProxy(m_spinBox);
hbl->setMargin(0);
hbl->setSpacing(0);

hbl->addWidget(m_spinBox);
hbl->addWidget(m_toolButton);
}

QSpinBox *spinBox() const { return m_spinBox; }
QToolButton *toolButton() const { return m_toolButton; }

private:
QSpinBox *m_spinBox;
QToolButton *m_toolButton;
};
//-------------------------------------------------
class ItemDelegate: public QItemDelegate
{
Q_OBJECT

public:
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;

private slots:
void test();
};

aekilic
27th March 2009, 09:33
Dear Spirit

Thank you very much for all your help, not I have work out everything but only problem I have is

I get the data loaded on the actiong like this,


QAction *action = qobject_cast<QAction *>(sender());
if (action)
{
birimFiyat = action->data().toDouble();
}


But I need the double to be in


void ProformaDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
MyComplexEditor *mce = static_cast<MyComplexEditor *>(editor);
if (!mce)
return;
model->setData(index, gosteri.arg(birimFiyat,0,'f',2) + " " + totalParaBirimi, Qt::DisplayRole);
}



Can any body help?

spirit
31st March 2009, 13:48
I don't understand why do you need that action?
you need to get data prom spinbox by pressing tool button, right?
if yes, then I don't see any sense of using action, just process clicked signal of tool button and then in a slot do next


...
emit commitData(widget);
emit closeEditor(widget, QAbstractItemDelegate::SubmitModelCache);
...

where widget it's you complex widget.
so, try this


QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(option);
Q_UNUSED(index);

MyComplexEditor *mce = new MyComplexEditor(parent);
connect(mce->toolButton(), SIGNAL(clicked()), SLOT(test()));

return mce;
}

void ItemDelegate::test()
{
QMessageBox::information(0, tr("information"), tr("test"));
QToolButton *toolButton = qobject_cast<QToolButton *>(sender());
if (!toolButton)
return;
MyComplexEditor *mce = qobject_cast<MyComplexEditor *>(toolButton->parentWidget());
if (!mce)
return;
emit commitData(mce);
emit closeEditor(mse, QAbstractItemDelegate::SubmitModelCache);
}

after that setModelData will be called and data will be set in model.
btw, you don't need to chage this method setModelData leave it as is.
hope this helps. :)

aekilic
31st March 2009, 14:36
No I need the action because I bring the actions from sql amd evey action has a different number which I set them by setData.

I need to set those numbers to spin when I select from tool.

spirit
31st March 2009, 14:42
sigh, then you need:
1. add actions in complex editor
2. create needed connection
3. process triggered signals
4. set values in spinbox.

then you need modify you delegate in this way:
1. remove connect(mce->toolButton(), SIGNAL(clicked()), SLOT(test()));
2. remove test slot.
3. leave setModelData as is.

aekilic
31st March 2009, 17:32
I have tried this


connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(w->spinBox()->setValue(fiyat_tipleri.value(4).toDouble())));


But it didnt work:(

faldzip
31st March 2009, 17:39
you can't connect signal to a slot when signal has less number of parameters than slot wants to get. Because from where that slot should take those missing arguments?
and SLOT(asd()) uses asd() as "asd()" character string (or even something like "2asd()" or more complicated :]), not a function call.

spirit
31st March 2009, 17:41
I have tried this


connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(w->spinBox()->setValue(fiyat_tipleri.value(4).toDouble())));


But it didnt work:(

pretty wrong code. :)
ok, that's a new variant
h-file


class MyComplexEditor: public QWidget
{
Q_OBJECT

public:
MyComplexEditor(QWidget *parent = 0) : QWidget(parent)
{
m_spinBox = new QSpinBox();
m_toolButton = new QToolButton();
m_toolButton->setText("...");
QHBoxLayout *hbl = new QHBoxLayout(this);
m_spinBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_toolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
setFocusProxy(m_spinBox);
hbl->setMargin(0);
hbl->setSpacing(0);

hbl->addWidget(m_spinBox);
hbl->addWidget(m_toolButton);

for (int i = 0; i < 4; ++i) {
QAction *action = new QAction(tr("action%1").arg(i), this);
action->setData(i);
m_toolButton->addAction(action);
connect(action, SIGNAL(triggered()), SLOT(updateSpinBoxValue()));
}
}

QSpinBox *spinBox() const { return m_spinBox; }
QToolButton *toolButton() const { return m_toolButton; }

private slots:
void updateSpinBoxValue()
{
const QAction *action = qobject_cast<QAction *>(sender());
if (!action)
return;

m_spinBox->setValue(action->data().toInt());
}

private:
QSpinBox *m_spinBox;
QToolButton *m_toolButton;
};

cpp-file


QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
return new MyComplexEditor(parent);
}

void ItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
MyComplexEditor *mce = qobject_cast<MyComplexEditor *>(editor);
if (!mce)
return;
model->setData(index, mce->spinBox()->value());
}

select one of action and close editor (click on another item), data in cell will be stored to model.

aekilic
1st April 2009, 08:36
for the code you have sent, problem is I have to create my action in createEditor()

spirit
1st April 2009, 08:39
why do you have to do this?

aekilic
1st April 2009, 08:46
problem is load create action acording to the values in other columns. for example,

I have 3 rows and 6 columns

for each row I get values of columns 1 and 3 and create an action for the toolbar in column 6 acording to this. If there is no value either in 1 and 3 there wont be any action

spirit
1st April 2009, 08:52
so, I don't see any problem, make like this ;)
h-file


class MyComplexEditor: public QWidget
{
Q_OBJECT

public:
MyComplexEditor(QWidget *parent = 0) : QWidget(parent)
{
m_spinBox = new QSpinBox();
m_toolButton = new QToolButton();
m_toolButton->setText("...");
QHBoxLayout *hbl = new QHBoxLayout(this);
m_spinBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_toolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
setFocusProxy(m_spinBox);
hbl->setMargin(0);
hbl->setSpacing(0);

hbl->addWidget(m_spinBox);
hbl->addWidget(m_toolButton);
}

QSpinBox *spinBox() const { return m_spinBox; }
QToolButton *toolButton() const { return m_toolButton; }

public slots:
void updateSpinBoxValue()
{
const QAction *action = qobject_cast<QAction *>(sender());
if (!action)
return;

m_spinBox->setValue(action->data().toInt());
}

private:
QSpinBox *m_spinBox;
QToolButton *m_toolButton;
};

cpp-file


QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(option);
Q_UNUSED(index);

MyComplexEditor *mce = new MyComplexEditor(parent);
for (int i = 0; i < 4; ++i) {
QAction *action = new QAction(tr("action%1").arg(i), mce);
action->setData(i);
mce->toolButton()->addAction(action);
connect(action, SIGNAL(triggered()), mce, SLOT(updateSpinBoxValue()));
}
return mce;
}