QTreeView 绘制行的颜色
QTreeView color of painted row
我扩展了 QStyledItemDelegate
以在 QTreeView 的右侧绘制一些像素图。这很好用,但是,我意识到如果文本太长,像素图可能位于文本前面。
所以我在绘制像素图之前尝试绘制一个与背景颜色相同的矩形。
void MyItemDelegate::paint(
QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
...
QStyledItemDelegate::paint(painter, option, index);
...
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
...
painter->fillRect(rect, opt.backgroundBrush);
painter->drawPixmap(topLeft, pixmap);
}
我知道除了opt.backgroundBrush
之外所有变量都是正确的。无论有无 initStyleOption
调用,它始终是不可见的黑色。
然后我开始查看opt.state
和opt.features
的值,自己挑颜色。我在交替颜色 (QStyleOptionViewItem::Alternate
) 方面取得了一些成功,但它开始变得冗长乏味,因为还有其他状态(悬停和选中)和其他 OS 可能有其他状态。一定有更简单的方法。
所以,我的问题是:当我在 paint
方法中时,如何获得将用于绘制行的实际颜色?或者,您有什么其他干净的方法可以避免这种情况吗?
我的处理方式可能不同。我不会先打电话:
QStyledItemDelegate::paint(painter, option, index);
第一。
然后,重要的部分:如果您知道项目上有多少个图标,您就可以计算边界矩形。
你怎么知道你有多少个图标?也许通过调用类似的东西:
bool hasIcon = index->data(YourAPP::HasIcons).toBool();
你的委托中可以有这样的东西:
void MyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
...
QStyleOptionViewItem o = option;
initStyleOption(&o, index);
bool hasIcon = index->data(YourModel::HasIcons).toBool();
// or
bool hasCustomRole1 = index->data(YourModel::Role1).toBool();
bool hasCustomRole2 = index->data(YourModel::Role2).toBool();
if (hasIcon) {
// width of your icons, can be like o.rect.height() * numbers of icons
int width = 0;
// shrink your first rectangle
o.rect.adjust(0, 0, -width, 0);
// create a second rectangle
QStyleOptionViewItem o2 = option;
initStyleOption(&o2, index);
o2.rect.adjust(width, 0, 0, 0);
// paint your icons
...
painter->drawPixmap(o2, pixmap);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
如@G.M 所建议。我使用 QItemDelegate
class 而不是 QStyledItemDelegate
并且我对绘图过程有更多的控制。特别是因为添加了 protected functions,例如 drawDisplay
。覆盖此方法,我可以将 "display rectangle" 调整为比 Qt 计算的更小的大小。
void ActionsItemDelegate::drawDisplay(
QPainter *painter,
const QStyleOptionViewItem &option,
const QRect &rect,
const QString &text) const
{
const int minX = ...; // x position of the left-most icon
const int iconsWidth = rect.width() - (minX - rect.x());
QItemDelegate::drawDisplay(painter, option, rect.adjusted(0, 0, -iconsWidth, 0), text);
}
缺点是UIchanges时使用QStyledItemDelegate
。我不知道如何获得两者的好处:正常样式和更多控件。
我扩展了 QStyledItemDelegate
以在 QTreeView 的右侧绘制一些像素图。这很好用,但是,我意识到如果文本太长,像素图可能位于文本前面。
所以我在绘制像素图之前尝试绘制一个与背景颜色相同的矩形。
void MyItemDelegate::paint(
QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
...
QStyledItemDelegate::paint(painter, option, index);
...
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
...
painter->fillRect(rect, opt.backgroundBrush);
painter->drawPixmap(topLeft, pixmap);
}
我知道除了opt.backgroundBrush
之外所有变量都是正确的。无论有无 initStyleOption
调用,它始终是不可见的黑色。
然后我开始查看opt.state
和opt.features
的值,自己挑颜色。我在交替颜色 (QStyleOptionViewItem::Alternate
) 方面取得了一些成功,但它开始变得冗长乏味,因为还有其他状态(悬停和选中)和其他 OS 可能有其他状态。一定有更简单的方法。
所以,我的问题是:当我在 paint
方法中时,如何获得将用于绘制行的实际颜色?或者,您有什么其他干净的方法可以避免这种情况吗?
我的处理方式可能不同。我不会先打电话:
QStyledItemDelegate::paint(painter, option, index);
第一。
然后,重要的部分:如果您知道项目上有多少个图标,您就可以计算边界矩形。
你怎么知道你有多少个图标?也许通过调用类似的东西:
bool hasIcon = index->data(YourAPP::HasIcons).toBool();
你的委托中可以有这样的东西:
void MyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
...
QStyleOptionViewItem o = option;
initStyleOption(&o, index);
bool hasIcon = index->data(YourModel::HasIcons).toBool();
// or
bool hasCustomRole1 = index->data(YourModel::Role1).toBool();
bool hasCustomRole2 = index->data(YourModel::Role2).toBool();
if (hasIcon) {
// width of your icons, can be like o.rect.height() * numbers of icons
int width = 0;
// shrink your first rectangle
o.rect.adjust(0, 0, -width, 0);
// create a second rectangle
QStyleOptionViewItem o2 = option;
initStyleOption(&o2, index);
o2.rect.adjust(width, 0, 0, 0);
// paint your icons
...
painter->drawPixmap(o2, pixmap);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
如@G.M 所建议。我使用 QItemDelegate
class 而不是 QStyledItemDelegate
并且我对绘图过程有更多的控制。特别是因为添加了 protected functions,例如 drawDisplay
。覆盖此方法,我可以将 "display rectangle" 调整为比 Qt 计算的更小的大小。
void ActionsItemDelegate::drawDisplay(
QPainter *painter,
const QStyleOptionViewItem &option,
const QRect &rect,
const QString &text) const
{
const int minX = ...; // x position of the left-most icon
const int iconsWidth = rect.width() - (minX - rect.x());
QItemDelegate::drawDisplay(painter, option, rect.adjusted(0, 0, -iconsWidth, 0), text);
}
缺点是UIchanges时使用QStyledItemDelegate
。我不知道如何获得两者的好处:正常样式和更多控件。