qt - 在 tableview,qt複選框和 itemDelegate

  显示原文与译文双语对照的内容
78 1

我正在執行一個從QitemDelegate繼承的複選框的實現,將它放入 QTableView 。

問題是,我在插入左邊的時候,我需要它的中心。

就像我所理解的,負責油漆的方法。我已經按如下方式寫了:

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);
}
时间:原作者:0个回答

86 2

在擴展 QItemDelegate 類時,它有一個 drawCheck() 函數,它將為你繪製一個名為checkbox的checkbox 。你可以在 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 createEditor() 方法中返回這裡BooleanWidget類的實例。在 setModelData() 和 setEditorData() 中,你現在可以將輸入小部件強制轉換為這裡 BooleanWidget:

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

然後使用 is/setchecked方法。

原作者:
68 1

這就是我在編輯器控制項中對allign的操作:

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;
}
原作者:
78 4

按如下方式解決了問題:

相信從 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

使用標記的檢查執行操作

原作者:
...