【问题标题】:Align checkable items in qTableWidget对齐 qTableWidget 中的可检查项
【发布时间】:2013-04-20 16:51:59
【问题描述】:

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

【问题讨论】:

  • 我认为唯一的方法是为第二列实现自定义“仅复选框”委托。在此处绘制复选框并删除选择框非常容易。如果需要,我可以提供 C++ 示例。
  • @DmitrySazonov 我已经解决了选择框问题,但是如果您有 c++ 示例显示如何在特定列中使用委托进行复选框项目对齐,请将其作为答案发布。

标签: python qt qt4 pyqt4 qtablewidget


【解决方案1】:

一个使用 pyqt4 的例子。改编自falsinsoft

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)

【讨论】:

    【解决方案2】:

    用法:

    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 );
        }
    
    }
    

    示例:

    需要改进的地方:

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

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

    【讨论】:

    • 我想就是这样。没有时间将它翻译成 python,但它似乎是合法的。赏金是你的
    • 如果您还有其他问题,请随时提出。
    【解决方案3】:

    那个矩形是一个焦点调整和cannot be hidden via an stylesheet

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

    1 - 看来你可以使用

     tablewidget->setFocusPolicy(Qt::NoFocus);
    

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

    2 - 将可检查的小部件设置为禁用,不能通过setFlags 选择。我不知道这是否是一个错误,但在我的 Qt 中,我仍然可以点击复选框

    3 - 通过setFlags 也将您的第一列设置为可检查,并且不要使用第二列。复选框将显示在与字符串相同的列中,但在左侧。

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

    还有你got here an example

    【讨论】:

    • 1 - tableWidget.setFocusPolicy(QtCore.Qt.NoFocus) 有助于焦点边框(我在表格中只有鼠标事件,所以 tnx ) 2 - 不能用 Python。 setCheckState 不起作用,我需要在某些情况下自动完成 3 - 不能。我有几列带有复选框,我需要将它们分开。 4 - 示例中的委托移除焦点(在第 1 项中解决),你能举个例子它用于对齐吗?
    猜你喜欢
    • 2018-07-28
    • 2021-06-01
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    相关资源
    最近更新 更多