2012-08-03 73 views
4

我正在執行從QitemDelegate繼承的CheckBox,將其放入QTableView中。tableview中的複選框和itemdelegate

問題是,當我插入flush flush時,我需要它居中。

據我瞭解負責油漆的方法。我寫它如下:

void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 
{ 
bool checkValue; 

QStyleOptionButton BtnStyle; 
BtnStyle.state = QStyle::State_Enabled; 

if(index.model()->data(index, Qt::DisplayRole).toBool() == true) 
{ 
BtnStyle.state |= QStyle::State_On; 
checkValue = true; 
}else{ 
BtnStyle.state |= QStyle::State_Off; 
checkValue = false; 
} 


BtnStyle.direction = QApplication::layoutDirection(); 
BtnStyle.rect = option.rect; 
QApplication::style()->drawControl(QStyle::CE_CheckBox,&BtnStyle,painter); 
QApplication::style()->drawControl(QStyle::CE_CheckBox,&BtnStyle,painter); 
} 

什麼是缺少出現居中?

,所以我必須委派:

.H

class BooleanWidget : public QWidget 
{ 
    Q_OBJECT 
    QCheckBox * checkBox; 

    public: 
    BooleanWidget(QWidget * parent = 0) 
    { 
     checkBox = new QCheckBox(this); 
     QHBoxLayout * layout = new QHBoxLayout(this); 
     layout->addWidget(checkBox,0, Qt::AlignCenter); 

    } 

    bool isChecked(){return checkBox->isChecked();} 
    void setChecked(bool value){checkBox->setChecked(value);} 
}; 

class CheckBoxDelegate : public QItemDelegate 
{ 
    Q_OBJECT 
private: 
    BooleanWidget *checkbox; 

public: 
    CheckBoxDelegate(QObject *parent); 
    ~CheckBoxDelegate(); 
    void setEditorData(QWidget *editor,const QModelIndex &index)const; 
    void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index)const; 
    QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &/* option */,const QModelIndex &/* index */)const; 
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; 

public slots: 
    void changed(bool); 

}; 

的.cpp

void CheckBoxDelegate::changed(bool value) 
{ 
    BooleanWidget *checkbox = static_cast<BooleanWidget*>(sender()); 
    emit commitData(checkbox); 
    emit closeEditor(checkbox); 
} 

QWidget *CheckBoxDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &/* option */,const QModelIndex &/* index */) const 
{ 
    BooleanWidget *editor = new BooleanWidget(parent); 
    connect(editor, SIGNAL(toggled (bool)), this, SLOT(changed(bool))); 

    return editor; 
} 

void CheckBoxDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const 
{ 
    int value = index.model()->data(index, Qt::DisplayRole).toInt(); 

    BooleanWidget *checkbox = static_cast<BooleanWidget*>(editor); 

    if(value == 1) 
    { 
     checkbox->setChecked(true); 
    } 
    else 
    { 
     checkbox->setChecked(false); 
    } 


} 

void CheckBoxDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const 
{ 
    BooleanWidget *checkBox = qobject_cast<BooleanWidget*>(editor); 
    Qt::CheckState value; 

    if(checkBox->isChecked()) 
     value = Qt::Checked; 
    else 
     value = Qt::Unchecked; 

    model->setData(index, value, Qt::DisplayRole); 
} 

void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 
{ 
    drawCheck(painter, option, option.rect, index.data().toBool() ? Qt::Checked : Qt::Unchecked); 
    drawFocus(painter, option, option.rect); 
} 

回答

6

如果要擴展的QItemDelegate類,它有一個drawCheck()功能,你會吸引你一箇中心複選框。你可以在paint()函數中使用它。

編輯:

下面是一個例子,假設你有一個叫BooleanEditor類,從QItemDelegate什麼繼承:

void BooleanEditor::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 
{ 
    drawCheck(painter, option, option.rect, index.data().toBool() ? Qt::Checked : Qt::Unchecked); 
    drawFocus(painter, option, option.rect); 
} 

爲了保持進入編輯模式時,中心的複選框,可以做這樣的事情:

class BooleanWidget : public QWidget 
{ 
    Q_OBJECT 
    QCheckBox * checkBox; 

    public: 
    BooleanWidget(QWidget * parent = 0) 
    { 
     checkBox = new QCheckBox(this); 
     QHBoxLayout * layout = new QHBoxLayout(this); 
     layout->addWidget(checkBox,0, Qt::AlignCenter); 
    } 

    bool isChecked(){return checkBox->isChecked();} 
    void setChecked(bool value){checkBox->setChecked(value);} 
}; 

而在你的ItemDelegates c reateEditor()方法返回此BooleanWidget類的一個實例。在您的setModelData()和setEditorData()現在可以投你輸入小部件此BooleanWidget:

BooleanWidget * widget = qobject_cast<BooleanWidget*>(editor); 

,然後使用是/ setChecked方法。

+0

能舉個例子嗎?因爲據我看到,該函數的構造如下:drawCheck(QPainter *畫家,常量QStyleOptionViewItem&選項,QRect&rect,Qt ::狀態); – jackajack 2012-08-09 20:16:32

+0

我添加了一個例子。如果你想讓它可編輯(而不僅僅是顯示),那麼你應該重寫你的tablemodels flags()函數。 – 2012-08-09 20:30:10

+0

好的謝謝,我解決了問題的一部分。該檢查居中。現在的問題是,我把它放在QTableView中,點擊支票將被移到左邊而沒有選中。我必須給doubleclick來選擇 – jackajack 2012-08-09 20:42:35

1

解決如下問題:

認爲,從itemDelegate QStyledItemDelegate繼承並重新實現方法「漆」和「editorEvent」。

在方法「editorEvent」中發出一個信號,指示選擇了哪一行。

下面是代碼

class ItemDelegate : public QStyledItemDelegate 
{ 
    Q_OBJECT 

signals: 
    void clickSignal(int); 


public: 
    ItemDelegate(QObject *parent = 0) 
     : QStyledItemDelegate(parent) 
    { 
    } 

    void paint (QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const 
    { 
     QStyleOptionViewItemV4 viewItemOption(option); 

     if (index.column() == 0) { 
      const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; 
      QRect newRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, 
               QSize(option.decorationSize.width() + 5,option.decorationSize.height()), 
               QRect(option.rect.x() + textMargin, option.rect.y(), 
                 option.rect.width() - (2 * textMargin), option.rect.height())); 
      viewItemOption.rect = newRect; 
     } 
     QStyledItemDelegate::paint(painter, viewItemOption, index); 

    } 

    virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, 
          const QModelIndex &index) 
    { 
     Q_ASSERT(event); 
     Q_ASSERT(model); 

     // make sure that the item is checkable 
     Qt::ItemFlags flags = model->flags(index); 
     if (!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled)) 
      return false; 
     // make sure that we have a check state 
     QVariant value = index.data(Qt::CheckStateRole); 
     if (!value.isValid()) 
      return false; 
     // make sure that we have the right event type 
     if (event->type() == QEvent::MouseButtonRelease) { 
      const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; 
      QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, 
                option.decorationSize, 
                QRect(option.rect.x() + (2 * textMargin), option.rect.y(), 
                 option.rect.width() - (2 * textMargin), 
                 option.rect.height())); 

     } else { 
      return false; 
     } 
     Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked 
           ? Qt::Unchecked : Qt::Checked); 




     emit(clickSignal(index.row())); 

     return model->setData(index, state, Qt::CheckStateRole); 
    } 


}; 

類在那裏我有一個連接QTableView中做到這一點:

connect(check,SIGNAL(clickSignal(int)),this,SLOT(CheckMark(int))); //check the itemDelegate 

與被標記的檢查執行的操作

1

這就是我所做的以編輯器控件爲中心對齊:

QWidget *checkBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { 
    QCheckBox *editor = new QCheckBox(parent); 
    editor->setTristate(allowTriState); //my class' variable 
    // this does the trick :) 
    editor->setStyleSheet("QCheckBox {margin-left: 43%; margin-right: 57%;}"); 
    // this should do it better 
    // editor->setStyleSheet("QCheckBox {margin-left: auto; margin-right: auto;}"); 
    // but in my case the checkbox is slightly to the left of original 
    return editor; 
}