Here is how to draw a button that spans 2 columns:
#include <QtGui>
int main(int argv, char **args)
{
QApplication app(argv, args);
QPushButton *foo = new QPushButton("foo");
QPushButton *bar = new QPushButton("bar");
QPushButton *baz = new QPushButton("baz");
QGridLayout *layout = new QGridLayout();
layout->addWidget(foo, 0, 0);
layout->addWidget(bar, 0, 1);
layout->addWidget(baz, 1, 0, 1, 2); // span 2 columns
QWidget window;
window.setLayout(layout);
window.setWindowTitle("test");
window.show();
return app.exec();
}
Running the code gives me:
If I change the layout in order to get a button, baz, that spans 2 rows I fail:
layout->addWidget(foo, 0, 0);
layout->addWidget(bar, 1, 0);
layout->addWidget(baz, 0, 1, 2, 1); // (try to) span 2 rows
Here is what I get:
Your layout is fine, the baz button is spanning two rows. The problem is that it doesn't use all the available space. You have to change the vertical resize policy of your button from Fixed to MinimumExpanding.
I added the following, after which all was well:
foo->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
bar->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
baz->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
(thanks)
Related
I have a form that was giving me a SegFault Exception so I broke it down and commented out everything but the mainwindow itself. Then I uncommented out the first 2 controls to display. I'm using a qgridlayout but it's not showing things correctly. When I show just the first item, it shows the label with the & instead of an underline - which makes sense since I don't show the "buddy". If I show both though or if I add the 'setBuddy' in then the buddy overwrites the label in the grid at 0,0. The label is supposed to be at 0,0 and the buddy/combo box is at 0, 1. I need to keep adding things in and my alternative is to use QHBoxLayouts repeatedly and I'm not nuts about that at all as things won't be aligned. Here's just the CPP code for the MainWindow to see:
QComboBox *MainWindow::getSourceComboBox()
{
if(mCboSource == nullptr)
{
mCboSource = new QComboBox(this);
mCboSource->addItems({{"URL", "Text", "Database"}});
mCboSource->setCurrentIndex(0);
mCboSource->setEditable(false);
//connect(mCboSource, SIGNAL(QComboBox::currentTextChanged(QString &)), this, SLOT(MainWindow::sourceChanged(QString &)));
}
return(mCboSource);
}
QLabel *MainWindow::getSourceLabel()
{
if(mLblSource == nullptr)
{
mLblSource = new QLabel("&Source:", this);
mLblSource->setBuddy(getSourceComboBox());
mLblSource->setAutoFillBackground(false);
}
return(mLblSource);
}
void MainWindow::initControls()
{
QGridLayout *layout = new QGridLayout(this);
layout->addWidget(this->getSourceLabel(), 0, 0, 1, 1);
layout->addWidget(this->getSourceComboBox(), 0, 1, 1, 1);
/*layout->addWidget(this->getConfigButton(), 0, 2);
layout->addWidget(this->getDBPathLabel(), 1, 0);
layout->addWidget(this->getDBPathText(), 1, 1);
layout->addWidget(this->getBrowseButton(), 1, 2);
layout->addWidget(this->getDataTable(), 2, 0, 1, 3);
layout->addWidget(this->getButtonPanel(), 3, 0, 1, 3);*/
setLayout(layout);
}
void MainWindow::initWindow()
{
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
initControls();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, mCboSource(nullptr)
//, mLblDBPath(nullptr)
, mLblSource(nullptr)
/*, mTxtDBPath(nullptr)
, mBtnBrowse(nullptr)
, mBtnConfig(nullptr)
, mTblData(nullptr)*/
{
initWindow();
}
MainWindow::~MainWindow()
{ }
But what could be wrong w/ the QT code???
You are adding items almost as a central widget so you need to create a central widget and add the items and layout to that then add that central widget to the main window. That should solve the problem!
I am creating a QFormLayout with some items like this:
QFormLayout *tableLayout = new QFormLayout();
QLineEdit *line1 = new QLineEdit();
QLineEdit *line2 = new QLineEdit();
tableLayout->addRow(tr("LineText1 "), line1);
tableLayout->addRow(tr("LineText2 "), line2);
After that I try to add this Layout to a QGridLayout like this:
QGridLayout *layout = new QGridLayout();
QPushButton *btn1 = new QPushButton();
QPushButton *btn2 = new QPushButton();
layout->addWidget(btn, 1, 1, 3, 3);
layout->addWidget(btn2, 1, 4);
layout->addLayout(tableLayout, 2, 4);
After I added the tableLayout, btn1 as width as 1 column and the tableLayout is as width as 3 columns.
I already tried to put the QFormLayout into a own widget and add the widget to the QGridLayout. But it didn't changed anything. The way I am doing that is the following:
QFormLayout *tableLayout = new QFormLayout();
QLineEdit *line1 = new QLineEdit();
QLineEdit *line2 = new QLineEdit();
tableLayout->addRow(tr("LineText1 "), line1);
tableLayout->addRow(tr("LineText2 "), line2);
QWidget *widget = new QWidget();
widget->setLayout(tableLayout);
QGridLayout *layout = new QGridLayout();
QPushButton *btn1 = new QPushButton();
btn1->setText("btn1");
QPushButton *btn2 = new QPushButton();
btn2->setText("btn2");
layout->addWidget(btn1, 1, 1, 3, 3);
layout->addWidget(btn2, 1, 4);
layout->addWidget(widget, 2, 4);
What is the reason for this strange situation? And how to solve it?
Here is a picture of the result:
And here is wat I want to have:
To build the design you want the first thing is to establish the position of the elements, remember that the position of the rows or columns start at 0, not at 1 as you do. The second part is to set the size policies, some widgets already have some established policy such as the QPushButton that stretches horizontally but not vertically so even if the rowSpan is large it will not change the height of the button, so we must change that behavior and finally the stretch.
#include <QApplication>
#include <QFormLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QSizePolicy>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QGridLayout *layout = new QGridLayout(&w);
QPushButton *btn1 = new QPushButton("Btn1");
btn1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
QPushButton *btn2 = new QPushButton("Btn2");
btn2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
QFormLayout *tableLayout = new QFormLayout();
QLineEdit *line1 = new QLineEdit();
QLineEdit *line2 = new QLineEdit();
tableLayout->addRow("LineText1 ", line1);
tableLayout->addRow("LineText2 ", line2);
layout->addWidget(btn1, 0, 0, 3, 3);
layout->addWidget(btn2, 0, 3);
layout->addLayout(tableLayout, 1, 3);
// column 0 x3
layout->setColumnStretch(0, 3);
// column 3 x1
layout->setColumnStretch(3, 1);
w.resize(640, 480);
w.show();
return a.exec();
}
Note that the QFormLayout will make the widgets always on top, so it will not necessarily occupy the height of the space offered by the QGridLayout.
I am trying to align QLabels in a simple GridLayout but this doesn't work seems to be a bug in QT 5.9 ?
Here is my snippet, everything is in a QDialog:
MyDialogue::MyDialogue(QWidget *parent) : QDialog(parent) {
QLabel *labelA = new QLabel(); labelA->setFixedSize(100, 25);
QLabel *labelB = new QLabel(); labelB->setFixedSize(100, 25);
QLabel *labelC = new QLabel(); labelC->setFixedSize(100, 25);
QLabel *labelD = new QLabel(); labelD->setFixedSize(100, 25);
labelA->setStyleSheet("background-color:blue");
labelB->setStyleSheet("background-color:yellow");
labelC->setStyleSheet("background-color:purple");
labelD->setStyleSheet("background-color:green");
QGridLayout *layout = new QGridLayout(this);
layout->addWidget(labelA, 1, 1);
layout->addWidget(labelB, 1, 2);
layout->addWidget(labelC, 2, 1, 2, 2);
layout->addWidget(labelD, 3, 1, 3, 2);
}
The result:
Ok I found the solution (my mistake) :
MyDialogue::MyDialogue(QWidget *parent) : QDialog(parent) {
QLabel *labelA = new QLabel();
QLabel *labelB = new QLabel();
QLabel *labelC = new QLabel();
QLabel *labelD = new QLabel();
labelA->setStyleSheet("background-color:blue");
labelB->setStyleSheet("background-color:yellow");
labelC->setStyleSheet("background-color:purple");
labelD->setStyleSheet("background-color:green");
QGridLayout *layout = new QGridLayout(this);
layout->addWidget(labelA, 1, 1);
layout->addWidget(labelB, 1, 2);
layout->addWidget(labelC, 2, 1, 1, 2);
layout->addWidget(labelD, 3, 1, 1, 2);
}
I was incorrectly thinking that for expanding a row along 2 columns (the case of labelC and labelD) I had to write the corrdinates of the starting cell (2,1) the actual position and then the ending cell (2,2). I was misguided by a Java layout manager that worked exactly that way. Just for the record here you just have to indicate the total number of row span and column span which is 2 in my case.
I am trying to adjust a LineEdit and PushButton width in a QDialog window. The LineEdit should be 20 times wider than then button, so it's long enough to show the whole path. Below is my code, I tried several ways, but they all got similar layout (see screenshot). I want to make the Option window at least 2 times wider to make the LineEdit wide enough. How should I do that?
This is my code:
this->setWindowTitle(tr("Options"));
QGridLayout* logLayout = new QGridLayout;
QLineEdit _logPathLE = new QLineEdit;
logLayout->addWidget(_logPathLE, 0, 0);
logLayout->setColumnStretch(0, 20); // 1st: try with setStretch
//_logPathLE->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); // 2nd try with setSizePolicy
//logLayout->addWidget(logLocation, 0, 0, 0, 20); // 3rd: try with span multiple columns
QPushButton* browseFolder = new QPushButton(tr("..."));
logLayout->addWidget(browseFolder, 0, 1);
logLayout->setColumnStretch(1, 1);
//browseFolder->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
//logLayout->addWidget(browseFolder, 0, 20, 0, 1);
QGroupBox* optGroupBox = new QGroupBox(tr("Log location"));
optGroupBox->setLayout(logLayout);
QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(btns, SIGNAL(accepted()), this, SLOT(accept()));
connect(btns, SIGNAL(rejected()), this, SLOT(reject()));
QVBoxLayout* options = new QVBoxLayout;
options->addWidget(optGroupBox);
options->addWidget(btns);
this->setLayout(options);
I have a QWidget which contains a QVBoxLayout and that layout contains a QLabel and QToolButtons. My problem is, that the QLabel takes all the space. The only solution I found is to set maximumHeight to the QLabel, but if I do that, the Qt::AlignTop doesn't work anymore.
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget window_main;
QWidget *widget_steps = new QWidget(&window_main);
widget_steps->setFixedWidth(75);
widget_steps->move(QPoint(0, 0));
widget_steps->setStyleSheet("background-color: red;");
QVBoxLayout *layout_steps = new QVBoxLayout(widget_steps);
layout_steps->setContentsMargins(0, 0, 0, 0);
layout_steps->setSpacing(0);
QLabel *label_steps_start = new QLabel("steps:");
label_steps_start->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
label_steps_start->setStyleSheet("background-color: blue;");
layout_steps->addWidget(label_steps_start);
QToolButton *tbutton_step1 = new QToolButton();
layout_steps->addWidget(tbutton_step1);
QToolButton *tbutton_step2 = new QToolButton();
layout_steps->addWidget(tbutton_step2);
QToolButton *tbutton_step3 = new QToolButton();
layout_steps->addWidget(tbutton_step3);
window_main.showMaximized();
return a.exec();
}
Here a picture that shows how much space the QLable takes(the blue space):
So please help to minimize the space the QLable takes :)
Your problem is that the tool buttons have a fixed size, and therefore when resizing, the label is the only type that can grow: Therefore:
After adding the label, add stretch to the layout:
layout_steps->addWidget(label_steps_start);
layout_steps->addStretch();
Modified code - adds stretch at the bottom. Label size remains fixed, and buttons remain under it. I've removed the whole main window around the outside for the sake of testing.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *widget_steps = new QWidget;
widget_steps->setFixedWidth(75);
widget_steps->move(QPoint(0, 0));
widget_steps->setStyleSheet("background-color: red;");
QVBoxLayout *layout_steps = new QVBoxLayout(widget_steps);
layout_steps->setContentsMargins(0, 0, 0, 0);
layout_steps->setSpacing(0);
QLabel *label_steps_start = new QLabel("steps:");
label_steps_start->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
label_steps_start->setStyleSheet("background-color: blue;");
layout_steps->addWidget(label_steps_start);
//--- Removed.... layout_steps->addStretch();
QToolButton *tbutton_step1 = new QToolButton();
layout_steps->addWidget(tbutton_step1);
QToolButton *tbutton_step2 = new QToolButton();
layout_steps->addWidget(tbutton_step2);
QToolButton *tbutton_step3 = new QToolButton();
layout_steps->addWidget(tbutton_step3);
layout_steps->addStretch(); //<----- Added!
widget_steps->show();
return a.exec();
}
One way you could do is to set the stretch factor for that particular widget inside the QVBoxLayout. You can find the documentation for that in here.
Basically, when you add a widget you can set that, for instance:
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QVBoxLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget window_main;
QWidget *widget_steps = new QWidget(&window_main);
widget_steps->setFixedWidth(75);
widget_steps->move(QPoint(0, 0));
widget_steps->setStyleSheet("background-color: red;");
QVBoxLayout *layout_steps = new QVBoxLayout(widget_steps);
layout_steps->setContentsMargins(0, 0, 0, 0);
layout_steps->setSpacing(0);
QLabel *label_steps_start = new QLabel("steps:");
label_steps_start->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
label_steps_start->setStyleSheet("background-color: blue;");
layout_steps->addWidget(label_steps_start, 3, Qt::AlignTop);
layout_steps->addStretch();
QToolButton *tbutton_step1 = new QToolButton();
layout_steps->addWidget(tbutton_step1, 1);
QToolButton *tbutton_step2 = new QToolButton();
layout_steps->addWidget(tbutton_step2, 1);
QToolButton *tbutton_step3 = new QToolButton();
layout_steps->addWidget(tbutton_step3, 1);
window_main.showMaximized();
return a.exec();
}