Update Widget Size In a QGridLayout?
-
I am trying to use two push buttons to insert/remove two QTextEdits into a QGridLayout. The parent widget is a QFrame with a fixed-size of 800*800.
However, I found the size of these QTextEdits are not updated correctly right after the insert/removal. Could anyone tell me how to update these size?
the code:
void Dialog::onButton0(bool is_toggled) { Editor1 = new QTextEdit; Editor1->setPlainText(tr("editor1 " "grid layout.")); if(is_toggled) { layout->addWidget(Editor1,0,0); qDebug()<<"editor1 GEO is "<<layout->itemAtPosition(0,0)->geometry(); qDebug()<<"editor1 bottom right corner is"<<layout->itemAtPosition(0,0)->geometry().bottomRight(); qDebug()<<"its parent widget size is "<<gridGroupBox->geometry(); }else{ layout->removeWidget(Editor1); } } void Dialog::onButton1(bool is_toggled) { Editor2 = new QTextEdit; Editor2->setPlainText(tr("editor2 " "grid layout.")); if(is_toggled) { layout->addWidget(Editor2, 0, 1); }else{ layout->removeWidget(Editor2); } qDebug()<<"editor1 GEO is "<<layout->itemAtPosition(0,0)->geometry(); qDebug()<<"editor1 bottom right corner is"<<layout->itemAtPosition(0,0)>geometry().bottomRight(); qDebug()<<"its parent widget size is "<<gridGroupBox->geometry(); }
And the debug print is:
insert the first QTextEdit:
editor1 GEO is QRect(0,0 640x480)
editor1 bottom right corner is QPoint(639,479)
editor1 corners at global are QPoint(560,153) and QPoint(1199,632)
its parent widget size is QRect(11,95 800x800)insert the second QTextEdit:
editor1 GEO is QRect(10,22 780x768)
editor1 bottom right corner is QPoint(789,789)
editor1 corners at global are QPoint(1107,268) and QPoint(1886,1035)
its parent widget size is QRect(11,95 800x800) -
By the way, I tried to use update() and updateGeometry() to manually update the QTextEdit widget size. But neither of them worked. However, calling Hide() and Show() did update the QTextEdit widget size after insertion. But this cannot update the other QTextEdit widget size while removing this one.
-
Hi and welcome to devnet,
Might be a silly question but did you set your layout on your QFrame widget ?
-
Are you talking about the debug out put which does not print the correct size of the QTextEdit ? OR
Your QTextEdit objects are not resized when you add them to layout ?Which one you are talking about ?
As side note, this has code may have memory leak. -
Hi and welcome to devnet,
Might be a silly question but did you set your layout on your QFrame widget ?
@SGaist Hi, thanks a lot for you hospitality and quick reply. Yes, I set my layout as following (I tried to use QGroupBox instead):
QGroupBox* gridGroupBox = new QGroupBox(tr("Grid layout")); gridGroupBox->setFixedSize(800,800); gridGroupBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QGridLayout* layout = new QGridLayout; gridGroupBox->setLayout(layout);
@dheerendra When I clicked the button0 to add the first QTextEdit editor1, it printed "editor1 GEO is QRect(0,0 640x480)", however, at this time, as the GUI shows, the editor1 actually occupies the entire parent QGroupBox. Then I clicked the button1 to add the second QTextEdit editor2, it printed "editor1 GEO is QRect(10,22 780x768)" but the GUI shows editor1 is actually half of the its previous size, it only occupied the half area of the parent QGroupBox. Therefor the size I retrieved using geometry is not correct. Even the coordinates of its corners mapped to global don't make sense to me. What I really want is to get the correct size by using functions like width() height() or geometry() of the child widgets in the QGridLayout on a timely manner.
Could you point out the potential memory problem please? -
You are trying to get the geometry before the widget is even show, that's why your numbers don't make sense.
Calling add doesn't mean that the widget is shown instantly code wise even if in the eye of the user it's the case. There will be several things happening. So if you really want to get the size of the widgets you should do it after the widgets are shown.
-
If you add a single QWidget to a gridlayout, the widget will try to take up the whole space the gridlayout has available.
if you dont want that to happen, you'll have to tell the widget that with
void QWidget::setFixedSize(const QSize &s); //and void QWidget::setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
if you want your widget to be effected by resizeEvents and you don't want it to take up all availabe space, you have to add Spaceritems.
e.g:
QSpacerItem *hSpacer = new QSpacerItem(10,10,QSizePolicy::Expanding,QSizePolicy::Minimum); QSpacerItem *vSpacer = new QSpacerItem(10,10,QSizePolicy::Minimum,QSizePolicy::Expanding); gridGroupBox->addWidget(Editor1,0,0); gridGroupBox->addItem(hSpacer,0,1); gridGroupBox->addItem(vSpacer,1,0);
With those 2 items, the Editor1 will take up 1/4 of the gridlayout (not considering margins and stuff. of course)
-
You are trying to get the geometry before the widget is even show, that's why your numbers don't make sense.
Calling add doesn't mean that the widget is shown instantly code wise even if in the eye of the user it's the case. There will be several things happening. So if you really want to get the size of the widgets you should do it after the widgets are shown.
@SGaist Hmm, thanks. Yes you are right. If I manually coded ->hide() and ->show() right after ->addwidget and before retrieving the size of THIS QWidget. I can get correct size. But it only works for the case of adding widget. In case of removing QWidget, (e.g., I need to retrieve correct size of Edit1 after I remove Edit2.), I guess a clumsy way is to hide() and show() every other QWidgets in this layout whenever removing a QWidget from this layout. Is there any cleverer way?
-
If you add a single QWidget to a gridlayout, the widget will try to take up the whole space the gridlayout has available.
if you dont want that to happen, you'll have to tell the widget that with
void QWidget::setFixedSize(const QSize &s); //and void QWidget::setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
if you want your widget to be effected by resizeEvents and you don't want it to take up all availabe space, you have to add Spaceritems.
e.g:
QSpacerItem *hSpacer = new QSpacerItem(10,10,QSizePolicy::Expanding,QSizePolicy::Minimum); QSpacerItem *vSpacer = new QSpacerItem(10,10,QSizePolicy::Minimum,QSizePolicy::Expanding); gridGroupBox->addWidget(Editor1,0,0); gridGroupBox->addItem(hSpacer,0,1); gridGroupBox->addItem(vSpacer,1,0);
With those 2 items, the Editor1 will take up 1/4 of the gridlayout (not considering margins and stuff. of course)
-
@SGaist Hmm, thanks. Yes you are right. If I manually coded ->hide() and ->show() right after ->addwidget and before retrieving the size of THIS QWidget. I can get correct size. But it only works for the case of adding widget. In case of removing QWidget, (e.g., I need to retrieve correct size of Edit1 after I remove Edit2.), I guess a clumsy way is to hide() and show() every other QWidgets in this layout whenever removing a QWidget from this layout. Is there any cleverer way?
my suggestion would be:
#include <QObject> #include <QTextEdit> #include <QResizeEvent> class cTextEdit: public QTextEdit { Q_OBJECT public: explicit cTextEdit(QWidget * parent = 0) : QTextEdit(parent){ } ~cTextEdit(){} signals: void newSize(QSize s); protected: virtual void resizeEvent(QResizeEvent *event); { emit newSize(event->size()); event->ignore(); } };