8

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

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

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

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

谢谢,鲍里斯。

4

4 回答 4

11

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

使用 QRadioButton 按钮作为标题

使用 QRadioButton 作为标题的布局

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

从单选按钮中删除文本

使用好友标签布局

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

于 2009-12-06T16:23:12.637 回答
3

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

于 2009-12-03T14:23:00.920 回答
2

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

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

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

于 2009-12-29T11:46:52.073 回答
0

我的解决方案:

#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
}
于 2015-09-03T13:13:55.343 回答