crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в CheckBox в QTableView
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
aasavelev Дата 9.2.2015, 19:58
  Реализую CheckBox в TableView. Но осталось одна проблема когда изменяю состояние CheckBox.оно не сохраняется в базу. Подскажите почему? Что нужно исправить?
#include "checkboxdelegate.h"

CheckBoxDelegate::CheckBoxDelegate(QObject *parent) :
    QItemDelegate(parent)
{
    checkBoxColumnIx = 4;
}

CheckBoxDelegate::~CheckBoxDelegate(){

}

QWidget *CheckBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem &option,
                      const QModelIndex &index) const
{
    if (index.column() == checkBoxColumnIx)
    {
        QCheckBox* chb = new QCheckBox(parent);
        this->connect(chb,SIGNAL(toggled(bool)),this,SLOT(commitAndCloseEditor()));
        chb->setStyleSheet("QCheckBox {margin-left: 43%; margin-right: 57%;}");
        //chb->setChecked(!chb->isChecked());
        return chb;
    } else {
        return QItemDelegate::createEditor(parent, option, index);
    }
}

void CheckBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if (index.column() == checkBoxColumnIx)
    {
        int checked = index.model()->data(index, Qt::DisplayRole).toInt();
        QCheckBox* chb = qobject_cast<QCheckBox*>(editor);
        chb->setChecked(checked == 1);
    } else {
        QItemDelegate::setEditorData(editor, index);
    }
}

void CheckBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    if (index.column() == checkBoxColumnIx)
    {
        // создаем элемент
        QCheckBox* chb = qobject_cast<QCheckBox*>(editor);
        // Эта функция интерпретирует
        // текст в spinbox. Если значение изменилось с момента
        // последней активации, то она будет излучать сигналы.
        // сохраняем значения счетчика в переменную
        int value;
        if(chb->isChecked()){
            value= 1;
        }else{
            value=0;
        }
        // меняем значение по координатам, на новое, из счетчика
        model->setData(index, value);

    } else {
        QItemDelegate::setModelData(editor, model, index);
    }
}

void CheckBoxDelegate::commitAndCloseEditor()
{
    QCheckBox* editor = qobject_cast<QCheckBox*>(sender());
    //editor->setChecked(!editor->isChecked());
    emit commitData(editor);
    emit closeEditor(editor);
}

void CheckBoxDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex & index ) const
{
    editor->setGeometry(option.rect);
}

/*!
  Отрисовка индикатора.
*/
void CheckBoxDelegate::paint(QPainter * painter, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
    if (index.sibling(index.row(),4).data(Qt::DisplayRole).toInt()== 0) {
        painter->fillRect(option.rect, QColor(0,0,0,0));
    } else {
        painter->fillRect(option.rect, QColor(211,211,211,255));
    }
    if (index.column() ==checkBoxColumnIx)
    {
        QWidget *w = dynamic_cast<QWidget *>(painter->device());
        if (w)
        {
            QItemDelegate::drawBackground( painter, option, index );
            QItemDelegate::drawCheck( painter, option, option.rect, index.data(Qt::EditRole).toBool() ? Qt::Checked : Qt::Unchecked );
            drawFocus(painter, option, option.rect);
        }
    } else {
        QItemDelegate::paint(painter, option, index);
    }
}

bool CheckBoxDelegate::editorEvent(QEvent * event, QAbstractItemModel * model,
                   const QStyleOptionViewItem & option, const QModelIndex & index)
{
    if (index.column()==checkBoxColumnIx){
        switch(event->type()){
            case QEvent::MouseButtonPress:{
                if(index.data(Qt::DisplayRole).toInt()==0){
                    model->setData(index,1);
                }else{
                    model->setData(index,0);
                }

                return true;
            }
        }
    }
    return false;
}
igor_bogomolov Дата 27.1.2010, 13:28
 
Цитата(Viper360 @ 27.1.2010, 13:15) *
Но все-же, как выровнять этот чекбокс по центру ячейки чтобы не кривилась прорисовка выделения?
Делал я себе набор делегатов-виджетов, один из них как раз check box. Приложил тестовый пример использующий его. У меня там, правда, свои заморочки, но его не сложно будет адаптировать под себя.

Litkevich Yuriy Дата 27.1.2010, 10:36
  Viper360, не приходилось заниматься такими вещами, но я бы пошёл по пути использования метода paint вместо drawCheck

void MyDelegate::paint (
        QPainter *painter,
        const QStyleOptionViewItem& option,
        const QModelIndex& index ) const {
...
}
по идее в этом методе можно с помощью QStyleOptionViewItem выставлять выравнивание (QStyleOptionViewItem::displayAlignment), надо поискать пример применения этого метода.

Цитата(Viper360 @ 27.1.2010, 13:15) *
Но все-же, как выровнять этот чекбокс по центру ячейки чтобы не кривилась прорисовка выделения?
есть ещё подозрение, что ты не верную область прорисовки задаёшь, без учёта области которая передаётся в метод drawCheck ты в нём игнорируешь аргумент - const QRect &
Viper360 Дата 27.1.2010, 10:15
 
Цитата(Litkevich Yuriy @ 27.1.2010, 6:58) *
Viper360, а как себя это представление ведёт если не устанавливать собственного делегата?


Да, именно при установке делегата появляются проблемы с выделением. Но как я говорил ранее, без него чекбоксы выравниваются по левому краю ячейки :



В ячейке слева есть маленький кусок, выделенный под чекбокс, четко его видно при изменении ширины столбца (с делегатом) :



Но все-же, как выровнять этот чекбокс по центру ячейки чтобы не кривилась прорисовка выделения?
Litkevich Yuriy Дата 27.1.2010, 7:58
  Viper360, а как себя это представление ведёт если не устанавливать собственного делегата?
Viper360 Дата 27.1.2010, 1:51
 
Цитата(Litkevich Yuriy @ 26.1.2010, 14:45) *
в методе vtabmodel::data, для роли Qt::DisplayRole, для столбца с флажком возвращай QVariant(), т.е. пустое значение, тогда текста ни какого не будет


Спасибо за ответ! Сделал как посоветовал, текста нет. Но впрочем нечего не изменилось, с выделением та же проблема :

Litkevich Yuriy Дата 26.1.2010, 15:45
  в методе vtabmodel::data, для роли Qt::DisplayRole, для столбца с флажком возвращай QVariant(), т.е. пустое значение, тогда текста ни какого не будет
Viper360 Дата 26.1.2010, 14:48
  Доброго времени суток! Подскажите, как побороть проблему с чекбоксами : унаследовал модель от QSqlQueryModel чтобы поля БД типа boolean отображались как Qt::CheckStateRole :

bool ischeck (QVariant data) {
    if (data.isValid())
        return (data.type()==QVariant::Bool) ? true : false;
    else return false;
}

vtabmodel::vtabmodel (QObject *parent)
        : QSqlQueryModel(parent)
{
}

Qt::ItemFlags vtabmodel::flags (const QModelIndex &index) const {
    Qt::ItemFlags flags=QSqlQueryModel::flags(index);
    if (ischeck(QSqlQueryModel::data(index)))
        flags=Qt::ItemIsUserCheckable;
    else
        flags|=Qt::ItemIsEditable;
    return flags;
}

QVariant vtabmodel::headerData (int section,Qt::Orientation orientation,int role) const {
    if (section<0||role!=Qt::DisplayRole)
        return QVariant();
    if (orientation==Qt::Vertical)
        return this->index(section,0).data(); // 0 - number of column
    return QSqlQueryModel::headerData(section,orientation,role); // horizontal header
}

QVariant vtabmodel::data(const QModelIndex &index,int role) const {
    QVariant value=QSqlQueryModel::data(index,role);
    QVariant data=QSqlQueryModel::data(index);
    if (ischeck(data))
        value.clear();
    if (role==Qt::CheckStateRole&&ischeck(data)) {
        return (data.toBool()) ? Qt::Checked : Qt::Unchecked;
    } else
        return value;
}


Но далее столкнулся с тем, что чекбокс выравнивается по левому краю ячейки и текст TRUE/FALSE (естественно) не пропадает. Пошел таким путем :

    if (ischeck(data))
        value.clear();


чтобы убрать текст, а для выравнивания создал делегат :

AlignItemDelegate::AlignItemDelegate (QObject *parent)
        : QItemDelegate(parent)
{
}

void AlignItemDelegate::drawCheck (QPainter *painter,const QStyleOptionViewItem &option,const QRect &,Qt::CheckState state) const {
    const int textMargin=QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin)+1;
    QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
                                          check(option,option.rect,Qt::Checked).size(),
                                          QRect(option.rect.x()+textMargin,option.rect.y(),
                                                option.rect.width()-(textMargin*2),option.rect.height()));
    QItemDelegate::drawCheck(painter,option,checkRect,state);
}


После чего вставил его в необходимые колонки с помощью setItemDelegateForColumn. Но самая большая беда осталась с выделением строк. Если выделять ячейку с чекбоксом, то выделение его закрывает (перекрывает), т.е. видно его только в том кусочке ячейки, в котором он было до установки делегата. И еще при установке делегата меняется стиль самого выделения, вместо красивой закругленной рамки появляется грубая заливка по контуру. Помогите пожалуйста, может кто решал схожие проблемы. Изначально решил свою проблему просто перекрыв QSqlQueryModel::flags и для полей с чекбоксами грубо установил flags=Qt::ItemIsUserCheckable; без возможности выделения, но сейчас появилась большая необходимость вспомнить о проблеме и решить ее. Очень надеюсь на помощь, либо подсказку. Заранее спасибо!
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 29.3.2024, 18:01