如何访问委托的 paint() 函数中的另一个索引?
How to access another index inside paint() function of delegate?
当鼠标悬停在 table 的一个单元格上时,我需要为该单元格的整行创建一个效果。这意味着我需要访问另一个索引。
在这种情况下,我做了一个for循环,运行从table的第一列到最后一列并为其设置效果。但它不起作用。当然是因为命令 drawText 没有任何输入参数作为索引。在这种情况下如何设置另一个索引的效果?
也欢迎其他解决方案。谢谢!
void TableDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
qDebug() << index.row() << index.column();
TableDataRow::Type type = static_cast<TableDataRow::Type>( index.data( Qt::UserRole ).toInt() );
QString text = index.data( Qt::DisplayRole ).toString();
int row = index.row();
if ( option.state & QStyle::State_MouseOver )
{
if ( type == TableDataRow::Type::Data )
{
painter->fillRect( QRect( 0, option.rect.topLeft().y(), option.rect.width()*numberOfColumns, option.rect.height() ), QColor( 249, 126, 18 ) );
for ( int i = 0; i < numberOfColumns; i++ )
{
QModelIndex indexOfRow = index.sibling( row, i );
painter->setPen( Qt::white );
painter->drawText( option.rect, Qt::AlignVCenter | Qt::TextWordWrap, text );
}
}
}
}
我了解到,如果鼠标位于行中的任何项目上,您想创建更改行文本颜色的效果,我认为为此没有必要使用委托,只需启用 mouseTracking
并覆盖 mouseMoveEvent
方法。
#include <QApplication>
#include <QMouseEvent>
#include <QStandardItemModel>
#include <QTableView>
class TableView: public QTableView{
public:
TableView(QWidget *parent = nullptr):
QTableView(parent)
{
setMouseTracking(true);
}
protected:
void mouseMoveEvent(QMouseEvent *event)
{
QModelIndex ix = indexAt(event->pos());
if(mRow != ix.row()){
changeRowColor(mRow);
if(ix.isValid())
changeRowColor(ix.row(), Qt::green, Qt::blue);
mRow = ix.row();
}
QTableView::mouseMoveEvent(event);
}
void leaveEvent(QEvent *event)
{
changeRowColor(mRow);
QTableView::leaveEvent(event);
}
private:
void changeRowColor(int row, const QColor & textColor=Qt::black, const QColor &backgroundColor=Qt::white){
if(!model())
return;
for(int i=0; i< model()->columnCount(); i++){
model()->setData(model()->index(row, i), textColor, Qt::ForegroundRole);
model()->setData(model()->index(row, i), backgroundColor, Qt::BackgroundRole);
}
}
int mRow = -1;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TableView w;
QStandardItemModel model(5, 5);
for(int i=0; i < model.rowCount(); i++){
for(int j=0; j < model.columnCount(); j++){
model.setItem(i, j, new QStandardItem(QString("%1-%2").arg(i).arg(j)));
}
}
w.setModel(&model);
w.show();
return a.exec();
}
更新:
既然您已经使用 QAbstractTableModel
创建了自己的模型,那么您必须实现 setData()
和 data()
方法来处理 Qt::ForegroundRole
和 Qt::BackgroundRole
角色.
在我的示例中,每个项目都具有以下结构:
struct Item{
QString text="";
QBrush textColor=Qt::black;
QBrush bgColor=Qt::white;
};
那么模型必须将数据保存在一个QList<QList<Item>> m_items;
中,假设上面的方法应该如下:
QVariant TableModel::data(const QModelIndex &index, int role) const{
if (!index.isValid())
return QVariant();
const Item & item = m_items[index.row()][index.column()];
if (role == Qt::DisplayRole)
return item.text;
else if (role == Qt::ForegroundRole) {
return item.textColor;
}
else if (role == Qt::BackgroundRole) {
return item.bgColor;
}
else
return QVariant();
}
bool TableModel::setData(const QModelIndex &index,
const QVariant &value, int role)
{
if (!index.isValid())
return false;
Item & item = m_items[index.row()][index.column()];
if(role == Qt::EditRole || role == Qt::DisplayRole){
item.text = value.toString();
}
else if (role == Qt::ForegroundRole) {
if(value.canConvert<QBrush>())
item.textColor = value.value<QBrush>();
}
else if (role == Qt::BackgroundRole) {
if(value.canConvert<QBrush>())
item.bgColor = value.value<QBrush>();
}
else
return false;
emit dataChanged(index, index);
return true;
}
完整的例子可以在下面找到link
当鼠标悬停在 table 的一个单元格上时,我需要为该单元格的整行创建一个效果。这意味着我需要访问另一个索引。
在这种情况下,我做了一个for循环,运行从table的第一列到最后一列并为其设置效果。但它不起作用。当然是因为命令 drawText 没有任何输入参数作为索引。在这种情况下如何设置另一个索引的效果?
也欢迎其他解决方案。谢谢!
void TableDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
qDebug() << index.row() << index.column();
TableDataRow::Type type = static_cast<TableDataRow::Type>( index.data( Qt::UserRole ).toInt() );
QString text = index.data( Qt::DisplayRole ).toString();
int row = index.row();
if ( option.state & QStyle::State_MouseOver )
{
if ( type == TableDataRow::Type::Data )
{
painter->fillRect( QRect( 0, option.rect.topLeft().y(), option.rect.width()*numberOfColumns, option.rect.height() ), QColor( 249, 126, 18 ) );
for ( int i = 0; i < numberOfColumns; i++ )
{
QModelIndex indexOfRow = index.sibling( row, i );
painter->setPen( Qt::white );
painter->drawText( option.rect, Qt::AlignVCenter | Qt::TextWordWrap, text );
}
}
}
}
我了解到,如果鼠标位于行中的任何项目上,您想创建更改行文本颜色的效果,我认为为此没有必要使用委托,只需启用 mouseTracking
并覆盖 mouseMoveEvent
方法。
#include <QApplication>
#include <QMouseEvent>
#include <QStandardItemModel>
#include <QTableView>
class TableView: public QTableView{
public:
TableView(QWidget *parent = nullptr):
QTableView(parent)
{
setMouseTracking(true);
}
protected:
void mouseMoveEvent(QMouseEvent *event)
{
QModelIndex ix = indexAt(event->pos());
if(mRow != ix.row()){
changeRowColor(mRow);
if(ix.isValid())
changeRowColor(ix.row(), Qt::green, Qt::blue);
mRow = ix.row();
}
QTableView::mouseMoveEvent(event);
}
void leaveEvent(QEvent *event)
{
changeRowColor(mRow);
QTableView::leaveEvent(event);
}
private:
void changeRowColor(int row, const QColor & textColor=Qt::black, const QColor &backgroundColor=Qt::white){
if(!model())
return;
for(int i=0; i< model()->columnCount(); i++){
model()->setData(model()->index(row, i), textColor, Qt::ForegroundRole);
model()->setData(model()->index(row, i), backgroundColor, Qt::BackgroundRole);
}
}
int mRow = -1;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TableView w;
QStandardItemModel model(5, 5);
for(int i=0; i < model.rowCount(); i++){
for(int j=0; j < model.columnCount(); j++){
model.setItem(i, j, new QStandardItem(QString("%1-%2").arg(i).arg(j)));
}
}
w.setModel(&model);
w.show();
return a.exec();
}
更新:
既然您已经使用 QAbstractTableModel
创建了自己的模型,那么您必须实现 setData()
和 data()
方法来处理 Qt::ForegroundRole
和 Qt::BackgroundRole
角色.
在我的示例中,每个项目都具有以下结构:
struct Item{
QString text="";
QBrush textColor=Qt::black;
QBrush bgColor=Qt::white;
};
那么模型必须将数据保存在一个QList<QList<Item>> m_items;
中,假设上面的方法应该如下:
QVariant TableModel::data(const QModelIndex &index, int role) const{
if (!index.isValid())
return QVariant();
const Item & item = m_items[index.row()][index.column()];
if (role == Qt::DisplayRole)
return item.text;
else if (role == Qt::ForegroundRole) {
return item.textColor;
}
else if (role == Qt::BackgroundRole) {
return item.bgColor;
}
else
return QVariant();
}
bool TableModel::setData(const QModelIndex &index,
const QVariant &value, int role)
{
if (!index.isValid())
return false;
Item & item = m_items[index.row()][index.column()];
if(role == Qt::EditRole || role == Qt::DisplayRole){
item.text = value.toString();
}
else if (role == Qt::ForegroundRole) {
if(value.canConvert<QBrush>())
item.textColor = value.value<QBrush>();
}
else if (role == Qt::BackgroundRole) {
if(value.canConvert<QBrush>())
item.bgColor = value.value<QBrush>();
}
else
return false;
emit dataChanged(index, index);
return true;
}
完整的例子可以在下面找到link