Добавление QSizeGrip в угол QLabel - PullRequest
3 голосов
/ 01 апреля 2012

Я пытаюсь создать виджет, который состоит из текстового дисплея, размер которого может быть изменен пользователем, захватившим правый нижний угол. До сих пор я смог сгенерировать это:

enter image description here

Я применил к макету красный фон, чтобы сделать его более понятным. Я использовал следующий код для генерации этого:

  m_sizeGrip = new QSizeGrip( this );
  m_layout = new QHBoxLayout( this );
  m_label = new QLabel( this );

  m_layout->setContentsMargins( QMargins() );
  m_layout->setSpacing( 0 );
  m_layout->addWidget( m_label );
  m_layout->addWidget( m_sizeGrip, 0, Qt::AlignBottom | Qt::AlignRight );

  setWindowFlags( Qt::SubWindow );

По сути, это горизонтальный макет с добавленной надписью и ручкой, который затем устанавливается на QWidget. Моя проблема в том, что я бы хотел, чтобы ручка находилась в правом нижнем углу метки, а не в родительском виджете. Я также хотел бы сделать его невидимым, оставив его включенным.

Или, возможно, я поступаю неправильно. Моя конечная цель - создать текстовый виджет, который может быть изменен пользователем по горизонтали или по вертикали, но не имеет видимого захвата, который мог бы скрыть текст. Я уже на правильном пути с кодом выше, или есть лучший способ добиться этого?

1 Ответ

1 голос
/ 19 мая 2012

Вы можете создать пользовательский QLabel для этого. Идея состояла бы в том, чтобы отслеживать события перемещения мыши (которые по умолчанию запускаются только при нажатии кнопки мыши) и изменять размер в зависимости от того, сколько мыши проехали с момента последнего события.

Это позволяет вам точно контролировать, как отображать "захват" (если он вообще есть) и какую форму он должен иметь. Вы можете ограничить изменение размера по вертикали или горизонтали (или нет).

Вот демонстрация того, как вы могли бы это сделать (изменяет размеры в обе стороны). Предупреждение: это может нанести ущерб вашему макету.

#include <QtGui>

class GripLabel: public QLabel
{
    Q_OBJECT

    public:
        GripLabel(QString const& title, QWidget* parent = 0)
            : QLabel(title, parent),
              resizing(false),
              gripSize(10, 10)
        {
            // Prevent the widget from disappearing altogether
            // Bare minimum would be gripSize
            setMinimumSize(100, 30);
        }

        QSize sizeHint() const
        {
            return minimumSize();
        }

    protected:
        bool mouseInGrip(QPoint mousePos)
        {
            // "handle" is in the lower right hand corner
            return ((mousePos.x() > (width()  - gripSize.width()))
                &&  (mousePos.y() > (height() - gripSize.height())));
        }

        void mousePressEvent(QMouseEvent *e)
        {
            // Check if we hit the grip handle
            if (mouseInGrip(e->pos())) {
                oldPos = e->pos();
                resizing = true;
            } else {
                resizing = false;
            }
        }

        void mouseMoveEvent(QMouseEvent *e)
        {
            if (resizing) {
                // adapt the widget size based on mouse movement
                QPoint delta = e->pos() - oldPos;
                oldPos = e->pos();
                setMinimumSize(width()+delta.x(), height()+delta.y());
                updateGeometry();
            }
        }

        void paintEvent(QPaintEvent *e)
        {
            QLabel::paintEvent(e);
            QPainter p(this);
            p.setPen(Qt::red);
            p.drawRect(width()-gripSize.width(), height()-gripSize.height(),
                       gripSize.width(), gripSize.height());
        }

    private:
        bool resizing;
        QSize gripSize;
        QPoint oldPos;
};

Образец основного:

#include "griplabel.h"

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QWidget *w = new QWidget;
    QPushButton *b = new QPushButton("button");
    GripLabel *l = new GripLabel("Hello");
    QHBoxLayout *y = new QHBoxLayout;
    y->addWidget(b);
    y->addWidget(l);
    y->setSizeConstraint(QLayout::SetFixedSize);
    w->setLayout(y);
    w->show();
    return app.exec();
}
...