2009-12-03 4 views
7

J'essaie d'avoir une checkbox/radiobutton multi-ligne avec Qt en utilisant QCheckbox/QRadioButton standard.QCheckbox/QRadioButton line wrap Qt4.6.0

Je n'ai pas trouvé la solution directe car QRadioButton{wrap:true;} n'a aucun effet. La seule chose possible serait d'accéder à la QRadioButton->label->setLineWrap(true) mais

  1. Je voudrais faire du concepteur
  2. ne pas avoir à réécrire un widget

Toute idée à côté de mettre un QRadioButton et un QLabel à côté les uns des autres?

Thx, Boris.

Répondre

3

La seule façon que je connaisse (mais qui n'est pas "configurable") est de mettre un signe dans une chaîne.

+0

Cela fonctionne dans Qt 5.6 – jtooker

11

Cela est en effet très ennuyeux et ne peut pas être résolu sans réimplémentation: l'étiquette utilise Qt::PlainText si je ne me trompe pas. Dans nos projets, l'équipe de l'UI a résolu cela avec deux approches.

En utilisant le bouton QRadioButton comme titre

Layout using the QRadioButton as a title http://i48.tinypic.com/97prtl.png

Réécrivez le texte QRadioButton de telle façon qu'il ne dispose que d'une brève description de l'option. Mettez un QLabel en dessous et ajoutez une description plus longue. Nous utilisons une police plus petite et une petite empreinte pour la rendre nette. Ceci est fréquemment utilisé dans Mac OS X, par exemple.

Retrait du texte à partir du bouton radio

Layout using buddy labels http://i46.tinypic.com/wwhrgh.png

Restructurer l'interface utilisateur de sorte que chaque bouton radio est mis sur la gauche d'un QLabel. Ajoutez le texte entier au QLabel et définissez l'étiquette comme le copain des boutons radio. C'est l'approche la moins fonctionnelle, car cliquer sur l'étiquette ne vérifie pas le bouton radio. De plus, l'alignement n'est pas très bon.

+0

Merci pour votre répondre. J'ai résolu mon problème avec la 2ème solution que vous avez expliqué. Ce n'est pas très bon dans la mise en page mais ça fonctionne ... J'espère vraiment que Qt va résoudre ce problème dans un futur proche! Merci encore de toute façon. –

2

J'ai réussi à ajouter une mise en page et une étiquette en tant qu'enfant pour le bouton radio et en modifiant la stratégie de taille verticale sur Préféré (au lieu de Fixe). Malheureusement, cela ne l'a pas automatiquement fait réagir à la souris et clique comme le label natif, mais regardez un hack: Je setStyleSheet ("border: none") pour le bouton radio et il a commencé à fonctionner. Peut-être que c'est une caractéristique qui se passe dans les coulisses; J'aimerais avoir une certaine certitude.

Et l'indicateur peut être aligné avec "QRadioButton :: indicateur {subcontrol positions: en haut à gauche}" <-http://doc.trolltech.com/qq/qq20-qss.html

0

Ma solution:

#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 
}