对齐qTableWidget中的可检查项目

时间:2013-04-26 13:28:59

标签: python qt qt4 pyqt4 qtablewidget

在tableWidget中,我有一列完全由可检查项组成。 我无法弄清楚如何使复选框居中或至少删除旁边的文本框。 正如你在这张图片enter image description here上看到的那样,当我点击单元格时,文本框有那个丑陋的轮廓,如果可能,我希望在整个表格中关闭它。 我已经读过我需要使用代表来控制项目/图标的位置,但对于像我这样的人来说理解这一点需要很长时间,因此如果有一些简单的解决方案可以减少该列丑陋,请举例说明。

3 个答案:

答案 0 :(得分:7)

使用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)

答案 1 :(得分:4)

用法:

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

CheckBoxDelegate.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

CheckBoxDelegate.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方法。

答案 2 :(得分:3)

该矩形是一个焦点重复和cannot be hidden via an stylesheet

编辑: 所以你有四个选项:

1 - 似乎你可以使用

 tablewidget->setFocusPolicy(Qt::NoFocus);

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

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

3 - 将第一列设置为setFlags可检查,并且不要使用第二列。复选框将显示在字符串的左侧。

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

而你got here an example