Russian Qt Forum
Июнь 17, 2024, 03:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [QT4.2.2] QCheckBox в QCombobox  (Прочитано 10217 раз)
odin
Гость
« : Февраль 03, 2007, 13:38 »

Подскажите реальное решение как всунуть чекбоксы в список QСomboBox
Записан
Tonal
Гость
« Ответ #1 : Февраль 04, 2007, 09:21 »

Устанавливаешь модель QComboBox::setModel
В модели:
при возврате флага (функция flags(...)) добовляешь Qt::ItemIsUserCheckable к остальным нужным флагам.
В data(...) и setData(...) отрабатываешь роль Qt::CheckStateRole
Записан
odin
Гость
« Ответ #2 : Февраль 06, 2007, 19:49 »

извини плиз..... но в QT новичок.... нельзя ли примерчик подкинуть..
за ранее премного благодарен:)
Записан
Tonal
Гость
« Ответ #3 : Февраль 07, 2007, 15:45 »

Вот кусок модели с чеками, правда на python-е но на С++ переносится без проблем. ;-)
Код:

class SelMunObrMolel(QAbstractListModel):
  def flags(self, index):
    ret = super(SelMunObrMolel, self).flags(index)
    if ret != QtCore.Qt.ItemFlags():
      return ret | QtCore.Qt.ItemIsUserCheckable

  def data(self, index, role=QtCore.Qt.DisplayRole):
    if not index.isValid() or index.row() >= len(self.objects):
      return QtCore.QVariant()
    if role == QtCore.Qt.CheckStateRole:
      is_checked = self.objects[index.row()].is_checked
      return QtCore.QVariant(
        (QtCore.Qt.Unchecked, QtCore.Qt.Checked)[is_checked]
      )
    return super(SelMunObrMolel, self).data(index, role)

  def setData(self, index, value, role=QtCore.Qt.DisplayRole):
    if not index.isValid() or index.row() >= len(self.objects):
      return False
    if role == QtCore.Qt.CheckStateRole:
      obj = self.objects[index.row()]
      obj.is_checked = value == QtCore.QVariant(QtCore.Qt.Checked)
      return True
    return super(SelMunObrMolel, self).setData(index, value, role)
Записан
odin
Гость
« Ответ #4 : Февраль 07, 2007, 22:01 »

от Питона я как от Луны:)..... но всё равно спасибо.... пимеры из PyQt видел.. смысл понял.....
Записан
Pink_Panter
Гость
« Ответ #5 : Август 04, 2010, 12:45 »

Пробовал сделать как указано в теме, унаследовал модель, переопределил flag, data, setData
подключаю модель к TableView - есть чекбоксы. Подключаю к QComboBox - нет чекбоксов.
Попробовал подсунуть - чекбоксу QStyledItemDelegate с помощью setItemDelegate - чекбоксы стали отображаться, но не переключаются. Только если открывать комбобокс в месте, где потом появятся чекбоксы.
Записан
Pink_Panter
Гость
« Ответ #6 : Август 05, 2010, 12:01 »

Небольшое дополнение.
Qt 4.6.2, OS - Ubuntu 10.04 32 bit
Чекбоксы так-же начинают отображаться при установки QListView с помощью setView для QComboBox.
но вот управлять чекбоксами так и не получается.
Если просто разместить на форме QListView  с той же моделью - все работает нормально.
Вопрос - как все таки можно пробросить управление от комбобокса к его View или делегату ?
Записан
asvil
Гость
« Ответ #7 : Август 05, 2010, 15:48 »

Есть еще данное решение:
http://da-crystal.net/GCMS/blog/checkboxlist-in-qt/
Перейдя по ссылке Вы увидите, что на представление устанавливается фильтр сообщений, который перехватывает клик, тем самым не давая сработать поведению qcombobox'а на данный клик. Возможно Вам это поможет.
Записан
Pink_Panter
Гость
« Ответ #8 : Август 06, 2010, 06:37 »

Спасибо.
Мне попадалась эта статья, но я раньше её отбрасывал т.к. мне не понравилось, что наследуется делегат, причем он заточен на Qt::UserRole для управления чекбоксами. Что отличается от стандартного Qt::CheckStateRole.

Сейчас перечитал её более внимательно и увидел вот такую вещь:
Код:
// Enable editing on items view
view()->setEditTriggers(QAbstractItemView::CurrentChanged);
Попробую поиграться в этом направлении.
Записан
Pink_Panter
Гость
« Ответ #9 : Август 10, 2010, 20:19 »

Если кому будет интересно - вот результат, который в принципе меня устроил. "мелочь" которая мне не нравится - это то, что чекбокс ставится/снимается щелчком в любом месте итема, а не только в квадратике.
Код:
#include "qcombocheckbox.h"
#include <QListView>
#include <QMouseEvent>

////////////////////////////////////////////////////////////////////////////////////
// конструктор
////////////////////////////////////////////////////////////////////////////////////
QComboCheckBox::QComboCheckBox(QWidget *parent) :
    QComboBox(parent)
{
    // заменяем стандартный вьювер
    m_listView = new QListView(this);
    setView(m_listView);
    // устанавливаем перехват событий
    m_listView->viewport()->installEventFilter(this);
    // флаг открытия комбобокса
    m_opening = false;
}

////////////////////////////////////////////////////////////////////////////////
//  Перехватчик событий для работы чекбоксов
////////////////////////////////////////////////////////////////////////////////
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();
}
Основная идея при написании кода - минимум "велосипедизма".
Записан
crossly
Гость
« Ответ #10 : Август 10, 2010, 21:10 »

кстати... наследоватся совсем не обязательно.... надо было просто не только модель подсунуть комбобоксу но и вью. ( setView)
Записан
Pink_Panter
Гость
« Ответ #11 : Август 12, 2010, 04:18 »

Не совсем так.
Для того что бы чекбоксы не только отображались, но и работали, пришлось наследоваться. По крайней мере в моем случае.
Записан
PavelVX
Гость
« Ответ #12 : Ноябрь 21, 2011, 12:36 »

спасибо за наводку, как это вообще реализовывать!
Но не могли бы вы объяснить новичку, что я делаю не так?
Qt 4.7.4
Код:
//qcombocheckbox.h
#include <QtGui>


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;

};

В самой проге делаю следующее:
Код:
    QComboCheckBox * comboCheckBox = new QComboCheckBox(this);
    QSqlQueryModel * comboCheckModel = new QSqlQueryModel;
    comboCheckModel->setQuery("SELECT \"Kop\" FROM \"Opers\" ");
    comboCheckBox->setModel(comboCheckModel);
    comboCheckBox->show();
Значения появляются, но нет галочки для check! Где-то я неправильно модель инициализирую, но понять не могу. Подскажите пожалуйста!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.114 секунд. Запросов: 21.