3

MyDelegateに使用されるデリゲートがありQListWidgetます。デリゲートは から派生しQStyledItemDelegateます。の目標の 1 つは、 のMyDelegate各行にチェックボックス ボタンを配置することですListWidgetpaint()次のイベント内で実行されますMyDelegate

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyledItemDelegate::paint(painter, option, index);
    // ... drawing other delegate elements

    QStyleOptionButton checkbox;
    // setting up checkbox's size and position

    // now draw the checkbox
    QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkbox, painter);
}

を指定したので、最初はチェックボックスをクリックすると自動的に状態が変わると思いましたQStyle::CE_CheckBox。しかし、そうではありません。チェックボックスの視覚的な動作を手動で指定する必要があるようです。

データ的には、ユーザーがそのチェックボックスをクリックすると、特定の信号が発せられ、シーン データが変更されます。でこのアクションを実行しますeditorEvent():

bool MyDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)  
{
    if (event->type() == QEvent::MouseButtonRelease) {
        if (/* within checkbox area */)
            emit this->clickedCheckbox(index);
    }
}  

バックエンド部分が機能します。ただし、チェックボックスボタンの視覚状態をチェックからチェック解除、およびその逆に変更する方法がわかりません。

paint()から次のようなことを行うことで、チェックボックスの状態を手動で変更できることに気付きました。

checkbox.state = someCondition? (QStyle::State_Enabled | QStyle::State_On) :
                           (QStyle::State_Enabled | QStyle::State_Off) ;

QStyle::State_On/Offチェックボックスの状態を手動で変更するトリックを行います。

しかし、それを設定する方法と、どこに設定すればよいかわかりませんsomeConditionboolチェックボックス領域がクリックされたときに設定されるプライベート変数として導入しようとしましたeditorEvent()が、目的の動作を生成しません。他のすべてのチェックボックスをListWidget同じ視覚状態に設定します。そのため、すべてのチェックボックスのグローバル条件のように動作しました。

私の仕事を達成するには、ボタンを再実装し、クリック時にチェックボックスの状態を変更する必要があるように感じます。しかし、私はこの方法で迷子になり、問題へのアプローチ方法がわかりません。QStyleOptionButtonAPIからは、clicked()使用できるメソッドやその他のメソッドが表示されません。

問題は、チェックボックスを視覚的にチェックボックスのように動作させるにはどうすればよいかということです。チェックボックスを再実装する必要がある場合、どのクラスを継承すればよいでしょうか?

4

2 に答える 2

5

チェックボックスの状態を説明する値を設定しMyDelegate::editorEvent、それを使用して適切なチェックボックスを描画できます。

const int CHECK_ROLE = Qt::UserRole + 1;

bool MyDelegate::editorEvent(QEvent *event,
                            QAbstractItemModel *model,
                            const QStyleOptionViewItem &option,
                            const QModelIndex &index)
{
    if (event->type() == QEvent::MouseButtonRelease)
    {
        bool value = index.data(CHECK_ROLE).toBool();

        // invert checkbox state
        model->setData(index, !value, CHECK_ROLE);

        return true;
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

void MyDelegate::paint(QPainter *painter, 
                      const QStyleOptionViewItem &option, 
                      const QModelIndex &index) const
{
    QStyleOptionButton cbOpt;
    cbOpt.rect = option.rect;

    bool isChecked = index.data(CHECK_ROLE).toBool();
    if (isChecked)
    {
        cbOpt.state |= QStyle::State_On;
    }
    else
    {
        cbOpt.state |= QStyle::State_Off;
    }

    QApplication::style()->drawControl(QStyle::CE_CheckBox, &cbOpt, painter);
}
于 2016-04-22T07:28:15.480 に答える