Хочу сделать QComboBox у которого элементами будут QCheckBox. Данные берутся с PostgreSQL сервака, но сохранять их обратно пока не требуется.
Для получения данных будет стандартный запрос, три колонки: bool(сам чек), capti (название которое с чеком светится), param (служебная инфа - очень нужная колонка, в ней инфа для пересчетов).
Порыл инет и наш форум, нашел
http://www.prog.org.ru/topic_4240_0.html и это
http://da-crystal.net/2008/06/checkbox-in-qcombobox/.
Второй случай все просто, но нельзя прикрутить модель со служебной инфой
а без нее смысла нет огород городить.
А в первом случае не получается прикрутить модель. Лыжи у меня походу не той модели
CheckBoxList.h
class QComboCheckBoxModel : public QSqlQueryModel {
Q_OBJECT
public:
QComboCheckBoxModel(QObject *parent = 0);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
private:
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
};
class QComboCheckBox: public QComboBox
{
Q_OBJECT;
public:
QComboCheckBox(QWidget *widget = 0);
virtual ~QComboCheckBox();
bool eventFilter(QObject * watched, QEvent * event);
void showPopup();
private:
QListView * m_listView;
bool m_opening;
};
CheckBoxList.cpp
////////////////////////////////////////////////////////////////////////////////////
// конструктор
////////////////////////////////////////////////////////////////////////////////////
QComboCheckBox::QComboCheckBox(QWidget *parent) :
QComboBox(parent)
{
// заменяем стандартный вьювер
m_listView = new QListView(this);
setView(m_listView);
// устанавливаем перехват событий
m_listView->viewport()->installEventFilter(this);
// флаг открытия комбобокса
m_opening = false;
}
QComboCheckBox::~QComboCheckBox()
{
}
////////////////////////////////////////////////////////////////////////////////
// Перехватчик событий для работы чекбоксов
////////////////////////////////////////////////////////////////////////////////
bool QComboCheckBox::eventFilter(QObject * watched, QEvent * event)
{
// проверка тика отловленного события
if (event->type() == QEvent::MouseButtonRelease)
{
// блокируем смену галочки при открытии
if (m_opening)
{
m_opening = false;
return QObject::eventFilter(watched, event);
}
// проверяем тип
if (watched->parent()->inherits("QListView"))
{
// приводим к нужным типам
QListView *tmp = (QListView *)(watched->parent());
QMouseEvent *mEvent = (QMouseEvent *)event;
QModelIndex ind = tmp->indexAt(mEvent->pos());
// меняем состояние cheched
bool checked = tmp->model()->data(ind,Qt::CheckStateRole).toBool();
tmp->model()->setData(ind,!checked,Qt::CheckStateRole);
// блокируем закрытие комбобокса
return true;
}
}
return QObject::eventFilter(watched, event);
}
////////////////////////////////////////////////////////////////////////////////
// функция раскрытия комбобокса
////////////////////////////////////////////////////////////////////////////////
void QComboCheckBox::showPopup()
{
// флаг открытия комбобокса
m_opening = true;
// вызываем функцию класса - предка
QComboBox::showPopup();
};
////////////////////////////////////////////////////////////////////////////////
// определяем модель для QComboCheckBox
////////////////////////////////////////////////////////////////////////////////
QComboCheckBoxModel::QComboCheckBoxModel(QObject *parent)
: QSqlQueryModel(parent) {
};
QVariant QComboCheckBoxModel::data(
const QModelIndex &index,
int role) const {
QVariant value = QSqlQueryModel::data(index, role);
if (index.column() == 0) value = value.toBool();
return value;
}
Qt::ItemFlags QComboCheckBoxModel::flags(
const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() == 0)
flags = flags | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
return flags;
}
bool QComboCheckBoxModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.column() == 0) return QSqlQueryModel::setData(index, value, role);
return true;
}
Собственно использование:
// QListView * tstView = new QListView(this);
// QComboCheckBox * tstView = new QComboCheckBox(this);
QTableView * tstView = new QTableView(this);
QComboCheckBoxModel * tstModel = new QComboCheckBoxModel(this);
strSQL = "SELECT 0, 'test', 'value' ";
tstModel->setQuery(strSQL);
tstView->setModel(tstModel);
В случае QTableView появляется и чекбокс и выбор true/false (почему - непонятно), в случае QListView - пустой список, а в случае QComboCheckBox сам комбобокс, но список не раскрывается.
Где и что я делаю не так???