"对齐可勾选项目在qTableWidg中"

2024-05-29 03:07:58 发布

您现在位置:Python中文网/ 问答频道 /正文

在tableWidget中,我有一个完全由可检查项组成的列。 我不知道如何将复选框居中,或者至少删除它旁边的文本框。 正如您在这张图片上看到的,enter image description here当我单击单元格时,文本框的轮廓很难看,如果可能的话,我希望在整个表中关闭它。 我已经读过了,我需要使用委托来控制项目/图标的位置,但是对于像我这样的nooby来说,要理解这一点需要太长时间,所以如果有一些简单的解决方案可以使该列不那么难看,请举例说明。


Tags: 项目图片解决方案复选框图标轮廓文本框委托
3条回答

用法:

pView->setItemDelegateForColumn( 1, new DELEGATE::CheckBoxDelegate( this ) );

复选框delegate.h

#ifndef CHECKBOXDELEGATE_H
#define CHECKBOXDELEGATE_H

#include <QStyledItemDelegate>
#include <QModelIndex>


namespace DELEGATE
{

    class CheckBoxDelegate
        : public QStyledItemDelegate
    {
        Q_OBJECT

    public:
        CheckBoxDelegate( QObject *parent );
        ~CheckBoxDelegate();

        void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
        bool editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index );

    private:
        QModelIndex m_lastClickedIndex;
    };

}


#endif // CHECKBOXDELEGATE_H

复选框Delegate.cpp

#include "CheckBoxDelegate.h"

#include <QApplication>
#include <QStyleOptionButton>
#include <QPainter>
#include <QEvent>
#include <QMouseEvent>


namespace DELEGATE
{

    CheckBoxDelegate::CheckBoxDelegate( QObject *parent )
        : QStyledItemDelegate( parent )
    {
    }

    CheckBoxDelegate::~CheckBoxDelegate()
    {
    }

    void CheckBoxDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
    {
        // Setting parameters
        Qt::CheckState state = (Qt::CheckState)index.data( Qt::CheckStateRole ).toInt();
        QStyleOptionButton opt;

        opt.state = QStyle::State_Enabled; // CheckBox enabled
        if ( option.state & QStyle::State_MouseOver )
            opt.state |= QStyle::State_MouseOver; // Mouse over sell
        switch ( state )  // Check box state
        {
        case Qt::Unchecked:
            opt.state |= QStyle::State_Off;
            break;
        case Qt::PartiallyChecked:
            opt.state |= QStyle::State_NoChange;
            break;
        case Qt::Checked:
            opt.state |= QStyle::State_On;
            break;
        }
        // Check box rect
        opt.rect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &opt, NULL );
        const int x = option.rect.center().x() - opt.rect.width() / 2;
        const int y = option.rect.center().y() - opt.rect.height() / 2;
        opt.rect.moveTo( x, y );

        // Optional: draw hover focus
        if ( option.state & QStyle::State_MouseOver )
            painter->fillRect( option.rect, QBrush( QColor( 0xff, 0xff, 0xaa, 0x60 ) ) );

        // Mandatory: drawing check box
        QApplication::style()->drawControl( QStyle::CE_CheckBox, &opt, painter );
    }

    bool CheckBoxDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
    {
        switch ( event->type() )
        {
        case QEvent::MouseButtonPress:
            m_lastClickedIndex = index;
            break;

        case QEvent::MouseButtonRelease:
            {
                if ( index != m_lastClickedIndex )
                    break;
                QMouseEvent *e = static_cast< QMouseEvent * >( event );
                if ( e->button() != Qt::LeftButton )
                    break;
                m_lastClickedIndex = QModelIndex();

                QStyleOptionButton opt;
                opt.rect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &opt, NULL );
                const int x = option.rect.center().x() - opt.rect.width() / 2;
                const int y = option.rect.center().y() - opt.rect.height() / 2;
                opt.rect.moveTo( x, y );

                if ( opt.rect.contains( e->pos() ) )
                {
                    // TODO: process click on checkbox logic
                    Qt::CheckState state = (Qt::CheckState)index.data( Qt::CheckStateRole ).toInt();
                    switch ( state )
                    {
                    case Qt::Unchecked:
                        state = Qt::PartiallyChecked;
                        break;
                    case Qt::PartiallyChecked:
                        state = Qt::Checked;
                        break;
                    case Qt::Checked:
                        state = Qt::Unchecked;
                        break;
                    }

                    model->setData( index, state, Qt::CheckStateRole );
                }
                return true;
            }

        default:
            break;
        }

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

}

样品:

sample

需要改进的主题:

  • 选择图
  • 鼠标悬停处理
  • 双击处理
  • 键盘编辑事件//google中有很多例子,stackoverflow

注意:您的模型应该为Qt::CheckStateRole角色处理setData方法。

这个矩形是一个焦点重新聚集和cannot be hidden via an stylesheet

编辑: 因此您有四个选项:

1-看起来你可以使用

 tablewidget->setFocusPolicy(Qt::NoFocus);

但是你将失去处理键盘事件的能力。 见FocusPolicy

2-将可检查的widgettitems设置为禁用,不可通过setFlags选择。我不知道这是不是一个bug,但在我的Qt中,我仍然会点击复选框

3-也可以将第一列设置为可检查的setFlags,不要使用第二列。复选框将显示在字符串左边的同一列中。

4-您不想创建的自定义委托。

而你got here an example

使用pyqt4的示例。改编自falsinsoft

qcheck box centre inside pyqt4 atble widget

table = QTableWidget()   
cell_widget = QWidget()
chk_bx = QCheckBox()
chk_bx.setCheckState(Qt.Checked)
lay_out = QHBoxLayout(cell_widget)
lay_out.addWidget(chk_bx)
lay_out.setAlignment(Qt.AlignCenter)
lay_out.setContentsMargins(0,0,0,0)
cell_widget.setLayout(lay_out)
tableWidget.setCellWidget(i, 0, cell_widget)

相关问题 更多 >

    热门问题