1

In a previous question, I was given code which shows a implementation of heightForWidth() (thanks, @Kuba Ober) that works, but it does so only for a top-level QWidget. I tried to reproduce it for a QMainWindow, but it did not work.

This is the code where heightForWidth() works for a top-level QWidget:

QWidget w;
QVBoxLayout * l = new QVBoxLayout(&w);
l->addWidget(new Widget);
w.show();

And this is where I try to implement the same for QMainWindow, but here it heightForWidth() has no effect (even though it gets called):

QMainWindow mainWnd;
QWidget *w = new QWidget;
QVBoxLayout * l = new QVBoxLayout(w);
l->addWidget(new Widget);
mainWnd.setCentralWidget(w);
// Second widget to take unused space.
QFrame * btm = new QFrame;
btm->setFrameShape(QFrame::Panel);
btm->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
l->addWidget(btm);
mainWnd.show();

So why doesn't the QMainWindow implementation work?

Community
  • 1
  • 1
sashoalm
  • 75,001
  • 122
  • 434
  • 781
  • 1. When you add a central widget, it's redundant to set its parent. Docs say: *QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.* – Kuba hasn't forgotten Monica Sep 29 '13 at 12:04
  • 2. If a `QObject` will have its parent set at *any time*, either upon creation or later, it must be allocated on the free store. This is probably just a typo in the example code, but I wanted to stress that. – Kuba hasn't forgotten Monica Sep 29 '13 at 12:06
  • I think part of the problem is that `heightForWidth()` is meant to be a trade-off-mechanism, where you trade one for the other. When `width()` grows, height must not increase. If it happens to work with simple layouts, more win for you, but I don't think it's really meant to be used in such a way. Qt itself *always* uses it such that as you increase the width, height never increases. It either stays put or decreases. Think of a menubar or other wrapped text. – Kuba hasn't forgotten Monica Sep 29 '13 at 12:21
  • At the moment it looks to me that getting it "working" the way you intend it to work may require patching QMainWindowLayout, although I'm not completely sure yet. – Kuba hasn't forgotten Monica Sep 29 '13 at 12:25
  • I changed the my code, is it correct now with regards to 1) and 2)? – sashoalm Sep 29 '13 at 12:39
  • Btw, to give some context, I was trying to create a 'square' widget for a sudoku game, that can grow/shrink when you resize the window, but always stays square. I don't need it to affect the actual top-level window, so long as the widget itself always stays square. May be I should just ask that in a separate question, something like "How do I make a square widget in Qt". – sashoalm Sep 29 '13 at 12:40
  • Square widget implies `heightForWidth()`, so you're stuck there :) – Kuba hasn't forgotten Monica Sep 29 '13 at 13:01

1 Answers1

0

First note that a QMainWindow requires something to be set as the central widget, even if it's a placeholder.

All you need to do, then, is to have a placeholder widget with a layout in it, like you already do, and only then put two widgets inside: the one you want to stay square, plus a placeholder to pick up unused space.

Alternatively, why are you insisting on the widget being square? Just paint the square section inside, and clear the rest with default background role.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • I tried adding a `QFrame` as a second widget, like in your code in the previous answer (see my edit), but it doesn't seem to change anything - the 'square' widget still takes all the available space of the `QMainWindow`. As for wanting a square widget, I thought that this is the more correct way to do it. The other solution is a bit hackish, I don't think a widget should have unused area. May be I can use a custom layout instead? – sashoalm Sep 29 '13 at 13:13
  • If you literally put the entire container widget from the other answer into the centralwidget, it shouldn't change the behavior of what's inside. If it does, it's a bug. – Kuba hasn't forgotten Monica Sep 29 '13 at 17:23
  • OK, I just tested it, I put the top-level QWidget from the previous answer as the central widget of a QMainWindow, and it's not working, while if I show it as a top-level widget, it works. – sashoalm Sep 29 '13 at 18:11
  • I'd suggest reporting it as a Qt bug. By not working I presume that the bottom QFrame does not appear? – Kuba hasn't forgotten Monica Sep 29 '13 at 19:14