2

I'd like to know if it's possible to store a QPushButton in a QVariant. More precisely, I am trying to use it in a QStandardItemModel with the function setData. Here's what I want to do :

QPushButton* button = new QPushButton("Update");
setData(index(0, 0), "Button");
setData(index(0, 1), button);

But obviously, it doesn't work like that so I tried this :

QVariant variant;
variant.setValue(button);
setData(index(0, 1), QVariant::fromValue(variant));

And it's not working either. I'd like to do it without using a QTableView (I know there is a setIndexWidget in this kind of view).

Thanks in advance!

IAmInPLS
  • 4,051
  • 4
  • 24
  • 57

2 Answers2

9

QVariant needs a metatype for types it can store. Qt provides a set of commonly used types, but you can simply extend it, using the Q_DECLARE_METATYPE Macro:

#include <QPushButton>
#include <QVariant>

Q_DECLARE_METATYPE(QPushButton*)

void foo() {
    QPushButton *b1 = new QPushButton("button");
    QVariant v = QVariant::fromValue(b1);
    QPushButton *b2 = qvariant_cast<QPushButton*>(v);
}

Note: If you want to use your custom metatypes also in queued slot connections or with QMetaMethod, you have to call qRegisterMetaType<QPushButton*>()

king_nak
  • 11,313
  • 33
  • 58
  • Thanks a lot for that! Do yo uhave any idea how I could display my button after that? `setData` allows me to display QString and QIcon, but I can't retrieve my button the same way – IAmInPLS Jan 29 '16 at 11:06
  • That depends on the View you are using, and which role you are using to set the data (your code uses `Qt::EditRole`). I don't think that provided views by Qt will handle a `QPushButton`... have a look at the Qt Model/View guide: http://doc.qt.io/qt-5/model-view-programming.html – king_nak Jan 29 '16 at 11:20
  • Mmh that's what I thought, guess I'll have to take another path... Thanks anyway for the initial answer :) – IAmInPLS Jan 29 '16 at 11:22
  • 1
    @Alexis If all you want is displaying a button for each entry in your view and interacting with it, you should consider to create a delegate for it. You simply can't use the model's data to pass an object to get it displayed. – Murphy Feb 20 '16 at 01:32
1

You can do something like this, to store it into a QVariant:

QVariant v = QVariant::fromValue((void *) button);

and to retrieve it from QVariant:

new_button_pointer = (QPushButton *) v.value<void *>();

Remember to use it with care! It's highly unsafe to handle pointers like this

bibi
  • 3,671
  • 5
  • 34
  • 50
  • Alright for the storage, but how can I display my button after that? Because setData takes `variant` in parameter, but I'd like to have my button :( – IAmInPLS Jan 29 '16 at 11:02