简体   繁体   中英

Stretching a QLabel in a QGridLayout

I am manually creating a set of QLabels that are being put into a QGridLayout, and should be distributed evenly. When I create a test form using the QT Designer and add a series of labels, and put them in a QGridLayout, the labels occupy the full size of their cells in the grid. When I do this manually in c++, the labels don't expand and say the minimum size for the text. I am able to get these labels to expand vertically, but not horizontally.

Here is how I'm creating the QGridLayout:

m_layout = new QGridLayout;
m_layout->setHorizontalSpacing( 1 );
m_layout->setVerticalSpacing( 1 );
m_layout->setContentsMargins(0,0,0,0);
m_layout->setMargin(0);
m_layout->setSizeConstraint( QGridLayout::SetDefaultConstraint );
//m_layout->setSizeConstraint( QGridLayout::SetMaximumSize );

When I change the size constraint, it does not affect the size of the labels at all, so then I assumed that the issue may lie on how I'm creating the labels, which happens like this:

QLabel *label = new QLabel;
label->setAlignment( Qt::AlignCenter );
label->setFrameStyle( QFrame::Raised );
label->setMinimumSize( QSize(0,0) );
label->setMaximumSize( QSize(16777215, 16777215) );
label->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );

Right now, all the QLabels are the same size, but eventually they will have differing sizes, which is why I'm using a packed-bin algorithm. I designed the algorithm around classes like this:

struct ButtonFittingNode
{
    ButtonFittingNode( QRect rectangle, QGridLayout *layout )
        : used( false )
        , node( rectangle )
        , down( NULL )
        , right( NULL )
        , m_layout( layout )
    { }

    ~ButtonFittingNode()
    {
        if ( down ) delete down;
        if ( right ) delete right;
    }

    ButtonFittingNode *findNode( QLabel *btn )
    {
        int w = 1;
        int h = 1;
        if ( this->used )
        {
            ButtonFittingNode *bfn = NULL;
            if ( this->right ) bfn = this->right->findNode( btn );
            if ( this->down && !bfn ) bfn = this->down->findNode( btn );
            return bfn;
        }
        else if ( ( w <= node.width() ) && ( h <= node.height() ) )
        {
            qDebug() << "Placing at " << node.x() << node.y();
            m_layout->addWidget( btn, node.y(), node.x(), w, h, Qt::AlignJustify );
            this->used = true;
            this->splitNode( QSize( w, h ) );
            return this;
        }

        return NULL;
    }

    void splitNode( QSize sz )
    {
        int w = 0, h = 0;

        // Create a down node
        w = this->node.width();
        h = this->node.height() - sz.height();
        if ( h > 0 )
        {
            QRect n( this->node.x(), this->node.y() + sz.height(), w, h );
            this->down = new ButtonFittingNode( n, m_layout );
        }

        // Create a right node
        w = this->node.size().width() - sz.width();
        h = sz.height();
        if ( w > 0 )
        {
            QRect n( this->node.x() + sz.width(), this->node.y(), w, h );
            this->right = new ButtonFittingNode( n, m_layout );
        }
    }

    bool                used;
    QRect               node;
    ButtonFittingNode   *down;
    ButtonFittingNode   *right;
private:
    QGridLayout         *m_layout;
};

Using a 3x2 grid, I get the following output:

在此处输入图片说明

Sorry, I had to blur the text, since this is a work related project, but grey is background, white is the label's background. As you can see, they are tall, but skinny. I want these labels to be tall and fat. Am I setting some of the attributes wrong?

This is all really simple. The size constraint of the layout has got nothing to do with what you're seeing. You're also including a bunch of useless boilerplate code. Get rid of explicit setting of minimum and maximum sizes unless you have some non-default sizes in mind. This is completely useless:

label->setMinimumSize( QSize(0,0) );
label->setMaximumSize( QSize(16777215, 16777215) );

You need to set the label's sizePolicy to Expanding in the horizontal direction. That's all there's to it:

label->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );

I see what you want from your bin packing system, but it won't work very well as-is, since the column/row sizes in the grid will vary as the grid gets resized. Your packer will choose some column/row spans based on then current row/column sizes. Upon resizing, the packer's decisions won't be adequate anymore.

What you really want is a custom layout that does all the packing on the fly. The flow layout example may be very close to what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM