2011-03-29 115 views
7
自绘的每一行“按钮”

我想画“可点击”图标(或按钮),在我用我自己的自定义“QAbstractItemDelegate”一而QListView的每一行派生类油漆。这些按钮可能随着行的自定义状态而改变(我可以在绘画过程中访问底层的数据结构)。的Qt:可点击与QAbstractItemDelegate

解决这个问题的最好方法是什么?

回答

6

免责声明:这可能不是最好的方式,但在这里你有完全控制权的方式。我们发现有必要使用绘图复选框来执行此操作。

您可以继承QStyledItemDelegate(或QAbstractItemDelegate可能工作..还没有尝试过)并重新实现了painteditorEvent方法。您可以使用QStyle::drawControl()(设置适当的样式选项后)绘制控制paint,然后手动测试在editorEvent鼠标命中并用它做什么。如果内存正确地为我服务,则此代码很大程度上受到启发(咳嗽,复制,咳嗽,咳嗽)从查看QStyledItemDelegate的Qt源代码。

void CheckBoxDelegate::paint(QPainter *painter, 
          const QStyleOptionViewItem &option, 
          const QModelIndex &index) const { 
    bool checked = index.model()->data(index, Qt::DisplayRole).toBool(); 

    if (option.state & QStyle::State_Selected) { 
    painter->setPen(QPen(Qt::NoPen)); 
    if (option.state & QStyle::State_Active) { 
     painter->setBrush(QBrush(QPalette().highlight())); 
    } 
    else { 
     painter->setBrush(QBrush(QPalette().color(QPalette::Inactive, 
               QPalette::Highlight))); 
    } 
    painter->drawRect(option.rect); 
    } 

QStyleOptionButton check_box_style_option; 
    check_box_style_option.state |= QStyle::State_Enabled; 
    if (checked) { 
    check_box_style_option.state |= QStyle::State_On; 
    } else { 
    check_box_style_option.state |= QStyle::State_Off; 
    } 
    check_box_style_option.rect = CheckBoxRect(option); 

    QApplication::style()->drawControl(QStyle::CE_CheckBox, 
            &check_box_style_option, 
            painter); 
} 

bool CheckBoxDelegate::editorEvent(QEvent *event, 
            QAbstractItemModel *model, 
            const QStyleOptionViewItem &option, 
            const QModelIndex &index) { 
    if ((event->type() == QEvent::MouseButtonRelease) || 
     (event->type() == QEvent::MouseButtonDblClick)) { 
    QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event); 
    if (mouse_event->button() != Qt::LeftButton || 
     !CheckBoxRect(option).contains(mouse_event->pos())) { 
     return true; 
    } 
    if (event->type() == QEvent::MouseButtonDblClick) { 
     return true; 
    } 
    } else if (event->type() == QEvent::KeyPress) { 
    if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space && 
     static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select) { 
     return false; 
    } 
    } else { 
    return false; 
    } 

    bool checked = model->data(index, Qt::DisplayRole).toBool(); 
    return model->setData(index, !checked, Qt::EditRole); 
} 
+0

感谢。会试一试。 – JasonGenX 2011-03-29 20:47:55

+1

有一个问题,我如何检测鼠标在给定行的区域上移动“进入”和“离开”? (如果我想要实现的鼠标光标下的当前行的高亮) – JasonGenX 2011-03-30 14:18:34

+0

我认为这是'的QEvent :: MouseMove',但我不能完全肯定。大概最容易做的事情是把一个'qDebug()<< event->型()'语句在那里,赶你的应用程序,然后通过杂草不管它吐出来找到你需要处理的事件。 – 2011-03-30 14:46:18