具有 3 种可能值的图像
image with 3 possibility of value
我想个性化第 3 列以包含 QCheckBox 小部件。我希望使用三个图标自定义这些 QCheckBox 小部件:1.png(默认状态)| 2.png(选中状态)| 3.png(禁用状态)。所以我可以使用具有以下实现的自定义委托来做到这一点:
#include "mydelegate.h"
#include <QCheckBox>
#include <QPainter>
#include <QKeyEvent>
#include <QtDebug>
#include <QApplication>
#include <QStyleOptionViewItem>
MyDelegate::MyDelegate(QObject* parent) :
QStyledItemDelegate(parent)
{
// 1.png
_icon.addPixmap(QPixmap("1.png"), QIcon::Active, QIcon::On);
// 2.png
_icon.addPixmap(QPixmap("2.png"), QIcon::Selected, QIcon::On);
// 3.png
_icon.addPixmap(QPixmap("3.png"), QIcon::Disabled, QIcon::On);
}
void MyDelegate::paint(QPainter* painter, const QStyleOptionViewItem&
option, const QModelIndex& index) const
{
if (index.column() != 2)
QStyledItemDelegate::paint(painter, option, index);
else
{
bool value = index.model()->data(index,
Qt::UserRole).toBool();
QStyleOptionButton buttonVis;
buttonVis.rect = option.rect;
buttonVis.iconSize = QSize(50, 50);
buttonVis.icon = _icon;
buttonVis.features |= QStyleOptionButton::Flat;
buttonVis.state |= value ? QStyle::State_Enabled : QStyle::State_None;
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonVis, painter);
}
}
bool MyDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,
const QStyleOptionViewItem& option, const QModelIndex& index)
{
if (event->type() == QEvent::MouseButtonRelease)
{
bool value = model->data(index, Qt::UserRole).toBool();
model->setData(index, !value, Qt::UserRole);
}
return true;
}
它适用于 1.png 和 3.png 而不是 2.png 的问题。我希望它适用于三个图标
不需要实现paint(...) 或使用editorEvent(...) 方法,只需要通过启用图标的选项来覆盖initStyleOption(...) 方法。
在下面的示例中,项目 (2, 2) 被选中,项目 (4, 2) 被禁用,其他项目被启用但未被选中,显示 3 种类型的图标:
#include <QtWidgets>
class MyDelegate: public QStyledItemDelegate
{
public:
MyDelegate(QObject *parent=nullptr):
QStyledItemDelegate(parent)
{
m_icon.addPixmap(QPixmap("1.png"), QIcon::Active, QIcon::On);
m_icon.addPixmap(QPixmap("2.png"), QIcon::Selected, QIcon::On);
m_icon.addPixmap(QPixmap("3.png"), QIcon::Disabled, QIcon::On);
}
void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override{
QStyledItemDelegate::initStyleOption(option, index);
if (index.column() == 2){
option->features |= QStyleOptionViewItem::HasDecoration;
option->icon = m_icon;
option->decorationSize = QSize(50, 50);
}
}
private:
QIcon m_icon;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTableWidget w(10, 4);
MyDelegate *delegate = new MyDelegate(&w);
w.setItemDelegate(delegate);
QTableWidgetItem *item = new QTableWidgetItem;
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
w.setItem(4, 2, item);
w.show();
return app.exec();
}
更新: OP 使用的术语不充分,因为它指的是小部件的状态(正常、选中、禁用),而是必须指示未选中的状态,部分查了查了。
#include <QtWidgets>
class MyDelegate: public QStyledItemDelegate
{
public:
MyDelegate(QObject *parent=nullptr):
QStyledItemDelegate(parent)
{
uncheckedIcon = QIcon("1.png");
partiallyCheckedIcon = QIcon("2.png");
checkedIcon = QIcon("3.png");
}
void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override{
QStyledItemDelegate::initStyleOption(option, index);
if (index.column() == 2){
QIcon m_icon;
QVariant value = index.data(Qt::UserRole);
Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
if(state == Qt::Unchecked)
option->icon = uncheckedIcon;
else if (state == Qt::PartiallyChecked)
option->icon = partiallyCheckedIcon;
else
option->icon = checkedIcon;
option->features |= QStyleOptionViewItem::HasDecoration;
option->decorationSize = QSize(50, 50);
}
}
bool editorEvent(QEvent* event, QAbstractItemModel* model,
const QStyleOptionViewItem& option, const QModelIndex& index) override
{
bool r = QStyledItemDelegate::editorEvent(event, model, option, index);
if(index.column() != 2)
return r;
if ((event->type() == QEvent::MouseButtonRelease)
|| (event->type() == QEvent::MouseButtonDblClick)
|| (event->type() == QEvent::MouseButtonPress)) {
if ((event->type() == QEvent::MouseButtonPress)
|| (event->type() == QEvent::MouseButtonDblClick))
return true;
QVariant value = index.data(Qt::UserRole);
Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
state = static_cast<Qt::CheckState>((state + 1) % 3);
return model->setData(index, state, Qt::UserRole);
}
return r;
}
private:
QIcon uncheckedIcon;
QIcon partiallyCheckedIcon;
QIcon checkedIcon;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTableWidget w(10, 4);
MyDelegate *delegate = new MyDelegate(&w);
w.setItemDelegate(delegate);
w.resize(640, 480);
w.show();
return app.exec();
}
我想个性化第 3 列以包含 QCheckBox 小部件。我希望使用三个图标自定义这些 QCheckBox 小部件:1.png(默认状态)| 2.png(选中状态)| 3.png(禁用状态)。所以我可以使用具有以下实现的自定义委托来做到这一点:
#include "mydelegate.h"
#include <QCheckBox>
#include <QPainter>
#include <QKeyEvent>
#include <QtDebug>
#include <QApplication>
#include <QStyleOptionViewItem>
MyDelegate::MyDelegate(QObject* parent) :
QStyledItemDelegate(parent)
{
// 1.png
_icon.addPixmap(QPixmap("1.png"), QIcon::Active, QIcon::On);
// 2.png
_icon.addPixmap(QPixmap("2.png"), QIcon::Selected, QIcon::On);
// 3.png
_icon.addPixmap(QPixmap("3.png"), QIcon::Disabled, QIcon::On);
}
void MyDelegate::paint(QPainter* painter, const QStyleOptionViewItem&
option, const QModelIndex& index) const
{
if (index.column() != 2)
QStyledItemDelegate::paint(painter, option, index);
else
{
bool value = index.model()->data(index,
Qt::UserRole).toBool();
QStyleOptionButton buttonVis;
buttonVis.rect = option.rect;
buttonVis.iconSize = QSize(50, 50);
buttonVis.icon = _icon;
buttonVis.features |= QStyleOptionButton::Flat;
buttonVis.state |= value ? QStyle::State_Enabled : QStyle::State_None;
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonVis, painter);
}
}
bool MyDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,
const QStyleOptionViewItem& option, const QModelIndex& index)
{
if (event->type() == QEvent::MouseButtonRelease)
{
bool value = model->data(index, Qt::UserRole).toBool();
model->setData(index, !value, Qt::UserRole);
}
return true;
}
它适用于 1.png 和 3.png 而不是 2.png 的问题。我希望它适用于三个图标
不需要实现paint(...) 或使用editorEvent(...) 方法,只需要通过启用图标的选项来覆盖initStyleOption(...) 方法。
在下面的示例中,项目 (2, 2) 被选中,项目 (4, 2) 被禁用,其他项目被启用但未被选中,显示 3 种类型的图标:
#include <QtWidgets>
class MyDelegate: public QStyledItemDelegate
{
public:
MyDelegate(QObject *parent=nullptr):
QStyledItemDelegate(parent)
{
m_icon.addPixmap(QPixmap("1.png"), QIcon::Active, QIcon::On);
m_icon.addPixmap(QPixmap("2.png"), QIcon::Selected, QIcon::On);
m_icon.addPixmap(QPixmap("3.png"), QIcon::Disabled, QIcon::On);
}
void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override{
QStyledItemDelegate::initStyleOption(option, index);
if (index.column() == 2){
option->features |= QStyleOptionViewItem::HasDecoration;
option->icon = m_icon;
option->decorationSize = QSize(50, 50);
}
}
private:
QIcon m_icon;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTableWidget w(10, 4);
MyDelegate *delegate = new MyDelegate(&w);
w.setItemDelegate(delegate);
QTableWidgetItem *item = new QTableWidgetItem;
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
w.setItem(4, 2, item);
w.show();
return app.exec();
}
更新: OP 使用的术语不充分,因为它指的是小部件的状态(正常、选中、禁用),而是必须指示未选中的状态,部分查了查了。
#include <QtWidgets>
class MyDelegate: public QStyledItemDelegate
{
public:
MyDelegate(QObject *parent=nullptr):
QStyledItemDelegate(parent)
{
uncheckedIcon = QIcon("1.png");
partiallyCheckedIcon = QIcon("2.png");
checkedIcon = QIcon("3.png");
}
void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override{
QStyledItemDelegate::initStyleOption(option, index);
if (index.column() == 2){
QIcon m_icon;
QVariant value = index.data(Qt::UserRole);
Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
if(state == Qt::Unchecked)
option->icon = uncheckedIcon;
else if (state == Qt::PartiallyChecked)
option->icon = partiallyCheckedIcon;
else
option->icon = checkedIcon;
option->features |= QStyleOptionViewItem::HasDecoration;
option->decorationSize = QSize(50, 50);
}
}
bool editorEvent(QEvent* event, QAbstractItemModel* model,
const QStyleOptionViewItem& option, const QModelIndex& index) override
{
bool r = QStyledItemDelegate::editorEvent(event, model, option, index);
if(index.column() != 2)
return r;
if ((event->type() == QEvent::MouseButtonRelease)
|| (event->type() == QEvent::MouseButtonDblClick)
|| (event->type() == QEvent::MouseButtonPress)) {
if ((event->type() == QEvent::MouseButtonPress)
|| (event->type() == QEvent::MouseButtonDblClick))
return true;
QVariant value = index.data(Qt::UserRole);
Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
state = static_cast<Qt::CheckState>((state + 1) % 3);
return model->setData(index, state, Qt::UserRole);
}
return r;
}
private:
QIcon uncheckedIcon;
QIcon partiallyCheckedIcon;
QIcon checkedIcon;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTableWidget w(10, 4);
MyDelegate *delegate = new MyDelegate(&w);
w.setItemDelegate(delegate);
w.resize(640, 480);
w.show();
return app.exec();
}