سؤال

I need a pushbutton to either fill or not fill the entire space provided by a QGridLayout cell upon the creation of the button (the alignment value is loaded from file). I've simplified my situation with the following code. During run-time, users can set the alignment of the button - either making it fill the entire layout cell or nicely centered. It works so long as the button didn't start off with NULL alignment specified. Yet, I need the ability to start off with a NULL alignment (i.e. the button fills the space of the layout cell). When initially aligning with NULL, what is getting set to make the button lock into a AlignVCenter setting and how can I get the button to return to acting like it was initialized with something other than null alignment?

I'm using Qt 4.8 on Ubuntu 12.04 LTS

#include <QPushButton>
#include <QGridLayout>
#include <QMainWindow>
#include <QApplication>

class MyWidget : public QWidget {
    Q_OBJECT
    QPushButton* m_pb;
    QGridLayout* m_gl;
protected slots:
    void pbClicked();
public:
    MyWidget(QWidget* parent = 0);
};

MyWidget::MyWidget(QWidget* parent): QWidget(parent)
{
    m_pb = new QPushButton(tr("push me"));
    connect(m_pb, SIGNAL(clicked()), this, SLOT(pbClicked()));
    m_gl = new QGridLayout();
    //use (1) to see button expand when button is pressed
    //use (2) to show that I can't start off expanded
    /*1*/ //m_gl->addWidget(m_pb, 0, 0, Qt::AlignCenter); // creates desired effect
    /*2*/ //m_gl->addWidget(m_pb, 0, 0, 0); //does not create desired effect
    setLayout(m_gl);
}

void MyWidget::pbClicked(){
    //will expand button so long as initial alignment is not NULL
    m_gl->setAlignment(m_pb, 0);
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyWidget* widget = new MyWidget();
    QMainWindow window;
    window.setCentralWidget(widget);
    window.show();
    return app.exec();
}

#include "main.moc"
هل كانت مفيدة؟

المحلول

The "desired" behavior that you see is in fact an error, and I will file a bug report for it. Thanks for spotting it - nice corner case.

You need to set the size policy of the button to expanding in both directions. Buttons normally don't want to expand vertically, so if you tried a variant that toggles the alignment, you'd see that it works only horizontally, and that's correct.

This is a simple demonstration that shows the correct behavior that also fulfills your needs.

#include <QPushButton>
#include <QGridLayout>
#include <QApplication>

class AlignButton : public QPushButton {
    Q_OBJECT
    Qt::Alignment m_alignment;
    Q_SLOT void clicked()  {
        m_alignment ^= Qt::AlignCenter;
        parentWidget()->layout()->setAlignment(this, m_alignment);
        label();
    }
    void label() {
        setText(QString("Alignment = %1").arg(m_alignment));
    }
public:
    AlignButton(Qt::Alignment alignment, QWidget * parent = 0) :
        QPushButton(parent),
        m_alignment(alignment)
    {
        connect(this, SIGNAL(clicked()), SLOT(clicked()));
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        label();
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QWidget window;
    QGridLayout layout(&window);
    layout.addWidget(new AlignButton(0), 0, 0, 0);
    layout.addWidget(new AlignButton(Qt::AlignCenter), 1, 0, Qt::AlignCenter);
    window.setMinimumSize(500, 200);
    window.show();
    return app.exec();
}

#include "main.moc"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top