title: Qt: organizing my layout and QSizePolicy
body: <p>The main window of my Qt/C++ program looks like this:</p>
  
  <p><img src="https://i.stack.imgur.com/eKkTW.png" alt="main window"></p>
  
  <p>As you can see on the picture, the window consists essentially of:</p>
  
  <ul>
  <li>a menu on the left</li>
  <li>two "canvases"</li>
  </ul>
  
  <p>What I want is straightforward to describe: I want that under resizing of the window, both canvases take as much space as possible, but still remain squares (width = height). I've been trying to achieve that unsuccessfully.</p>
  
  <p>Let me quickly describe the objects:</p>
  
  <ul>
  <li>The window is a class <code>Window</code> that I created deriving QWidget. It has a <code>QGridLayout</code> for a layout.</li>
  <li>The window's layout has three widgets: the left menu <code>LeftMenu *menu</code>, and the canvases <code>Canvas *leftCanvas, *rightCanvas</code>. Both <code>LeftMenu</code> and <code>Canvas</code> are custom classes deriving QWidget.</li>
  </ul>
  
  <p>(NB: the left menu actually consists of 3 different widgets (submenus), and the window also has a status bar and a top menu, but I don't think it matters for my question.)</p>
  
  <p>I have been "playing" (not having fun the least bit) with QSizePolicy's etc to try to get the Canvases' sizes to behave like I want (be as large as possible inside the window, but keep height/width ratio = 1), unsuccessfully. Let me describe my latest attempt in case that is useful for you (if you already know a solution to my problem, you don't have to keep reading):</p>
  
  <p>I overrode the methods <code>heightForWidth()</code>, <code>sizeHint()</code> and <code>minimumSizeHint()</code> for Canvas like so:</p>
  
  <pre><code>class Canvas : public QWidget
  {
      Q_OBJECT
  
      friend class Window;
  
  public:
      explicit Canvas(Window* window);
      ...
  
  private:
      void resizeEvent(QResizeEvent *resizeEvent) override;
      int heightForWidth(int width) const override {return width;}
      QSize sizeHint() const override
      {
          int size = std::min(width(), height());
          return QSize(size, size);
      }
      QSize minimumSizeHint() const override {return QSize(200,200);}
      ...
  };
  </code></pre>
  
  <p>And the constructor of my class Window looks like (a bit simplified):</p>
  
  <pre><code>Window::Window(ActionHandler *handler)
  {
      leftMenu = new LeftMenu(this);
      leftMenu-&gt;setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
  
      leftCanvas = new Canvas(this);
      rightCanvas = new Canvas(this);
      QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Maximum);
      policy.setHeightForWidth(true);
      leftCanvas-&gt;setSizePolicy(policy);
      rightCanvas-&gt;setSizePolicy(policy);    
  
      layout = new QGridLayout;    
      layout-&gt;setColumnMinimumWidth(0, menuWidth());    
      layout-&gt;addWidget(leftMenu, 0, 0);
      layout-&gt;addWidget(leftCanvas, 0, 1);
      layout-&gt;addWidget(rightCanvas, 0, 2);
      setLayout(layout);
  }
  </code></pre>
  
  <p>My idea was that as long as the width of the canvases is the limiting factor, the <code>sizePolicy</code> of the canvases should be <code>(QSizePolicy::Expanding, QSizePolicy::Maximum)</code>. And as soon as the height of the canvases becomes the limiting factor, I would change the sizePolicy of the canvases (probably in <code>Canvas::resizeEvent()</code>) to the opposite: <code>(QSizePolicy::Maximum, QSizePolicy::Expanding)</code>. Does that sound too complicated?</p>
  
  <p>Anyway, it already fails, and I don't understand why. If I shrink the window horizontally it gives me this:</p>
  
  <p><img src="https://i.stack.imgur.com/nSDZ4.png" alt="enter image description here"></p>
  
  <p>So, the height of the canvases does not shrink. I do not understand this behavior. In the Qt documentation (<a href="http://doc.qt.io/qt-4.8/qsizepolicy.html#Policy-enum" rel="noreferrer">http://doc.qt.io/qt-4.8/qsizepolicy.html#Policy-enum</a>), I read:</p>
  
  <p><strong>QSizePolicy::Maximum</strong> <em>The sizeHint() is a maximum. The widget can be shrunk any amount without detriment if other widgets need the space (e.g. a separator line). It cannot be larger than the size provided by sizeHint().</em></p>
  
  <p>The behavior of my canvases here seems to contradict this: their height is larger than the height provided by their sizeHint(). (I did make sure by std::couting "live": the canvas sizeHint, its height, its sizePolicy and its hasHeightForWidth parameters).</p>