Adding a QSizeGrip to the corner of a QLabel

I am trying to create a widget that consists of a text display that can be modified by the user by grabbing the bottom right corner. So far I've managed to create this:

enter image description here

I applied a red layout to the layout to make it more obvious what is going on. I used the following code for this:

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

      

Basically it's a horizontal layout with label and chaining added, which is then set to the QWidget. My problem is that I would like the grip to be in the bottom right corner of the label and not in the form of the parent widget. I would also like to make it invisible by keeping it enabled.

Or maybe I am wrong. My end goal is to have a text widget that can be resized by the user horizontally or vertically, but has no visible capture that shades the text. Am I already on the right track with the code above, or is there a better way to achieve this?

+3


source to share


1 answer


For this you can create a custom QLabel

. The idea was to watch for mouse movement events (which by default only fire when a mouse button is pressed) and resize based on how many mice have moved since the last event.

This allows you to have precise control over how the "capture" is displayed (if at all) and what shape it should take. You can restrict resizing vertically or horizontally (or not).

Here's a demo of how you could do it (resizes in both directions). Warning: this can wreak havoc on your layout.



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

      

Basic example:

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

      

+1


source







All Articles