【问题标题】:QCheckbox/QRadioButton line wrap Qt4.6.0QCheckbox/QRadioButton 换行 Qt4.6.0
【发布时间】:2010-12-22 18:58:17
【问题描述】:

我正在尝试使用标准 QCheckbox/QRadioButton 在 Qt 中创建一个多行复选框/单选按钮。

我没有找到直接的解决方案,因为QRadioButton{wrap:true;} 没有效果。 唯一可能的方法是访问QRadioButton->label->setLineWrap(true),但是

  1. 我想从设计师那里做到这一点
  2. 不必重写小部件

除了将 QRadioButton 和 QLabel 放在一起之外有什么想法吗?

谢谢,鲍里斯。

【问题讨论】:

    标签: qt4 checkbox radio-button qcheckbox


    【解决方案1】:

    这确实很烦人,如果不重新实现就无法解决:如果我没记错的话,标签使用Qt::PlainText。在我们的项目中,UI 团队通过两种方法解决了这个问题。

    使用 QRadioButton 按钮作为标题

    重写 QRadioButton 文本,使其仅包含选项的简要说明。在它下面放一个 QLabel 并添加更长的描述。我们使用较小的字体和一点缩进使其看起来整洁。例如,这在 Mac OS X 中经常使用。

    从单选按钮中删除文本

    重新布局 UI,以便将每个单选按钮放在 QLabel 的左侧。将整个文本添加到 QLabel 并将标签设置为单选按钮的伙伴。这是功能最少的方法,因为单击标签不会选中单选按钮。另外,对齐也不是很好。

    【讨论】:

    • 感谢您的回答。我用你解释的第二个解决方案解决了我的问题。这在布局上不是很好,但很有效......我真的希望 Qt 能在不久的将来解决这个问题!无论如何,再次感谢。
    【解决方案2】:

    我知道的唯一方法(但它不是“可布局的”)是将 \n 符号放入字符串中。

    【讨论】:

      【解决方案3】:

      我成功地为单选按钮添加了一个布局和一个标签作为子项,并将垂直大小策略更改为首选(而不是固定)。

      不幸的是,这并没有像原生标签那样自动使其对鼠标悬停和点击做出反应,但请注意一个 hack:我为单选按钮设置了样式表(“border:none”),它开始工作了。也许这是幕后发生的一些功能;我很想确定一点。

      并且可以使用 "QRadioButton::indicator{subcontrol-position:top left}" http://doc.trolltech.com/qq/qq20-qss.html

      对齐指示器

      【讨论】:

        【解决方案4】:

        我的解决方案:

        #ifndef CHECKBOX_H
        #define CHECKBOX_H
        
        #include <QCheckBox>
        
        #include <QHBoxLayout>
        #include <QLabel>
        
        class CheckBox : public QCheckBox
        {
            Q_OBJECT
        public:
           explicit CheckBox(QWidget *parent = 0);
        
           void setText(const QString & text);
           QSize sizeHint() const;
           bool hitButton(const QPoint &pos) const;
        
        protected:
           void paintEvent(QPaintEvent *);
        
        private:
           QHBoxLayout* _layout;
           QLabel*      _label;
        };
        
        #endif // CHECKBOX_H
        
        
        
        
        #include "checkbox.h"
        
        #include <QStylePainter>
        #include <QStyleOption>
        
        #define MARGIN 4 // hardcoded spacing acording to QCommonStyle implementation
        
        CheckBox::CheckBox(QWidget *parent) : QCheckBox(parent)
        {
            setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::CheckBox));
        
            QStyleOptionButton opt;
            initStyleOption(&opt);
        
            QRect label_rect = style()->subElementRect(QStyle::SE_CheckBoxContents, &opt, this);
        
            _label = new QLabel(this);
            _label->setWordWrap(true);
            _label->setMouseTracking(true);
            //_label->setMinimumHeight(label_rect.height());
        
            _layout = new QHBoxLayout(this);
            _layout->setContentsMargins(label_rect.left()+MARGIN, MARGIN/2, MARGIN/2, MARGIN/2);
            _layout->setSpacing(0);
            _layout->addWidget(_label);
        
            setLayout(_layout);
        }
        
        void CheckBox::setText(const QString & text)
        {
            _label->setText(text);
            QCheckBox::setText(text);
        }
        
        void CheckBox::paintEvent(QPaintEvent *)
        {
            QStylePainter p(this);
            QStyleOptionButton opt;
            initStyleOption(&opt);
        
            QStyleOptionButton subopt = opt;
            subopt.rect = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &opt, this);
            subopt.rect.moveTop(opt.rect.top()+MARGIN/2); // align indicator to top
        
            style()->proxy()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &subopt, &p, this);
        
            if (opt.state & QStyle::State_HasFocus)
            {
                QStyleOptionFocusRect fropt;
                fropt.QStyleOption::operator=(opt);
                fropt.rect = style()->subElementRect(QStyle::SE_CheckBoxFocusRect, &opt, this);
                style()->proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, &p, this);
            }
        }
        
        QSize CheckBox::sizeHint() const
        {
            return QSize(); // will be calculated by layout
        }
        
        bool CheckBox::hitButton(const QPoint &pos) const
        {
            QStyleOptionButton opt;
            initStyleOption(&opt);
            return opt.rect.contains(pos); // hit all button
        }
        

        【讨论】:

        • 解决方案的开始非常好。但是,计算焦点矩形的计算算法应该改进(即“fropt.rect = style()->subElementRect(QStyle::SE_CheckBoxFocusRect, &opt, this);”),因为焦点矩形会与多行文本混淆,不要包围它。为确保系统会针对此类问题绘制出漂亮的焦点矩形,您需要为此类矩形设置适当的高度,因为多行文本具有不同的高度。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多