[SOLVED] ComboBox of CheckBoxes



  • Hi

    I need a combo box of check boxes. It should be able to connect signals of its checkboxes to some slots. also show selected choices in label. for example if user selects ch1 and ch2 and ch3 the label should something like this: "Selection: ch1, ch2 ch3" and if no check box is checked, it should be "Please select...".

    I guess I should play around models / views to obtain such widget. In documentation mentioned that QCombBox uses models and views internally. And it's possible to set it's model.

    What should I do?



  • Yes, your idea works. Here is a very easy way to test it:

    Get the following example from Qt example folder:
    examples/tutorials/modelview/2_formatting

    Now replace the QTableView with a QComboBox. The checkboxes which were meant for the QTableView are now visible in the QComboBox;



  • You are on the right track. You can subclass QComboBox, and use your own model for the options list. For that model, you can set the Qt::UserCheckable flag, so a checkbox is displayed. Then, listen to changes in the model data, and update the text accordingly.

    However, that is where the problems start. I don't see a straightforward way to manipulate the text of a non-editable QComboBox widget. I would have expected a virtual method for that. You could probably hack around this by using an editable QComboBox and manipulating the QLineEdit (you have access to it) to be in fact non-editable and basically look like a label. Not the nicest solution, but it should work.



  • bq. I don’t see a straightforward way to manipulate the text of a non-editable QComboBox widget.

    Andre, why do you think it is not possible to implement the setData() method of the model to collect mouseclicks on checkboxes?



  • Ok, I sublass QAbstractListModel and populate a new model containing a list of QCheckBox* s. Now displays checkboxes correctly but I couldn't managed to do editing things:
    @
    MyModel::MyModel(QObject parent)
    :QAbstractListModel(parent)
    {
    for(int i=0; i<10; i++)
    {
    QCheckBox
    x = new QCheckBox;
    x->setText(QString("Check Box %1").arg(i));
    list.append(x);
    }
    }

    int MyModel::rowCount(const QModelIndex & /*parent */) const
    {
    return list.length();
    }

    int MyModel::columnCount(const QModelIndex & /*parent */) const
    {
    return 1;
    }

    QVariant MyModel::data(const QModelIndex &index;, int role) const
    {
    if(role == Qt::CheckStateRole)
    return list[index.row()]->checkState();
    if(role == Qt::DisplayRole)
    return list[index.row()]->text();
    if(role == Qt::EditRole)
    {
    list[index.row()]->setCheckState( list[index.row()]->checkState() == Qt::Checked ? Qt::Unchecked:Qt::Checked );
    }

    return QVariant();
    

    }

    bool MyModel::setData(const QModelIndex &index;, const QVariant &value;, int role)
    {
    // This doesn't work
    list[index.row()]
    ->setCheckState( list[index.row()]->checkState() == Qt::Checked ? Qt::Unchecked:Qt::Checked );
    qDebug()<<role; // Anything... So method is not called ?
    }
    @



  • I set the editable flag and use the QLineEdit to show which choices are selected. Works fine

    Thanks



  • [quote author="dialingo" date="1310568540"]bq. I don’t see a straightforward way to manipulate the text of a non-editable QComboBox widget.

    Andre, why do you think it is not possible to implement the setData() method of the model to collect mouseclicks on checkboxes?[/quote]
    I don't think that at all. Where do I say that? I was talking about the currentText property of QComboBox.



  • soroush,
    I tried to use same code on Ubuntu 12.04. In addition to your code I added
    Qt::ItemFlags MyModel::flags(const QModelIndex & /index/) const
    {
    return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ;
    }
    Still Combo box not listing check box, only lists the label.
    Your help is much appreciated.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.