Qt/ModelView/ListViewComboBox
From ProgrammingExamples
< Qt
Contents
main.cpp
#include <QApplication> #include "form.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Form form; form.show(); return app.exec(); }
ComboBoxDelegate.h
#ifndef COMBOBOXDELEGATE_H #define COMBOBOXDELEGATE_H #include <string> #include <vector> #include <QItemDelegate> class QModelIndex; class QWidget; class QVariant; class ComboBoxDelegate : public QItemDelegate { Q_OBJECT public: ComboBoxDelegate(QObject *parent = 0); 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 paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; private: std::vector<std::string> Items; }; #endif
ComboBoxDelegate.cpp
#include "ComboBoxDelegate.h" #include <QComboBox> #include <QWidget> #include <QModelIndex> #include <QApplication> #include <QString> #include <iostream> ComboBoxDelegate::ComboBoxDelegate(QObject *parent) :QItemDelegate(parent) { Items.push_back("Test0"); Items.push_back("Test1"); Items.push_back("Test2"); } QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const { QComboBox* editor = new QComboBox(parent); for(unsigned int i = 0; i < Items.size(); ++i) { editor->addItem(Items[i].c_str()); } return editor; } void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QComboBox *comboBox = static_cast<QComboBox*>(editor); int value = index.model()->data(index, Qt::EditRole).toUInt(); comboBox->setCurrentIndex(value); } void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = static_cast<QComboBox*>(editor); model->setData(index, comboBox->currentIndex(), Qt::EditRole); } void ComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { editor->setGeometry(option.rect); } void ComboBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItemV4 myOption = option; QString text = Items[index.row()].c_str(); myOption.text = text; QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &myOption, painter); }
form.h
#ifndef FORM_H #define FORM_H #include "ui_form.h" #include <QMainWindow> #include "ComboBoxDelegate.h" class QStringListModel; class Form : public QMainWindow, private Ui::MainWindow { Q_OBJECT public: Form(QWidget *parent = 0); public slots: void on_btnAdd_clicked(); void slot_modelChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); protected: QStringListModel* Model; ComboBoxDelegate Delegate; }; #endif
form.cpp
#include <QtGui> #include <iostream> #include "form.h" Form::Form(QWidget *parent) : QMainWindow(parent) { setupUi(this); this->Model = new QStringListModel; this->listView->setModel(this->Model); connect(this->Model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slot_modelChanged(QModelIndex,QModelIndex))); this->listView->setItemDelegate(&this->Delegate); } void Form::on_btnAdd_clicked() { this->Model->insertRows(this->Model->rowCount(), 1); this->Model->setData(this->Model->index(this->Model->rowCount()-1), "new line " + QString::number(this->Model->rowCount())); } void Form::slot_modelChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { std::cout << "Model changed." << std::endl; // Make the combo boxes always displayed. for ( int i = 0; i < this->Model->rowCount(); ++i ) { this->listView->openPersistentEditor( this->Model->index(i) ); } }
form.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>232</width>
<height>489</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListView" name="listView"/>
</item>
<item>
<widget class="QPushButton" name="btnAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>232</width>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionSave"/>
</widget>
<addaction name="menuFile"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionSave">
<property name="text">
<string>Save</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>CMakeLists.txt
cmake_minimum_required(VERSION 2.6) PROJECT(ListViewSubclass) FIND_PACKAGE(Qt4 REQUIRED) INCLUDE(${QT_USE_FILE}) QT4_WRAP_UI(ListViewSubclass_UI form.ui) QT4_WRAP_CPP(ListViewSubclass_MOC form.h ComboBoxDelegate.h) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) ADD_EXECUTABLE(ListViewSubclass main.cpp form.h form.cpp ComboBoxDelegate.cpp ${ListViewSubclass_UI} ${ListViewSubclass_MOC}) TARGET_LINK_LIBRARIES(ListViewSubclass ${QT_LIBRARIES})