title: Custom widget in Qt Designer with pre-existing layout in frame
body: <p>A project uses  custom frame widget that implements a kind of "cover" that hides widgets (think of it as of security cover that prevents pressing buttons).This is a required visual design. Qt version is 4.6</p>
  
  <pre><code>#ifndef CQFRAME_H
  #define CQFRAME_H
  
  #include &lt;QFrame&gt;
  
  #include &lt;QtDesigner/QDesignerExportWidget&gt;
  
  //! [0] //! [1]
  class CQFrame : public QFrame   
  // our agreement about "custom" widgets is to start them with CQ
  {
      Q_OBJECT
      Q_ENUMS(FrameColorStyle)
  
      Q_PROPERTY(FrameColorStyle colorStyle READ getColorStyle WRITE setColorStyle)
      Q_PROPERTY(bool border READ border WRITE setBorder)
  //! [0]
  private:
      bool curCover;
      QFrame *frameCover;
  public:
      enum FrameColorStyle  {fcDark, fcLight, fcTransparent, fcSystemDefault, fcRed, fcGreen, fcBlue};
  
      CQFrame(QWidget *parent = 0);
  
      void setCoverPropertie();
      void setCover(bool state);
  protected:
      void resizeEvent(QResizeEvent *event);
      FrameColorStyle m_colorStyle;
      QString pstylebord;
      bool m_border;
  //! [2]
  };
  //! [1] //! [2]
  
  #endif
  </code></pre>
  
  <p>I omitted getters and setters that are irrelevant to the problem. Here is implementation:</p>
  
  <pre><code>void CQFrame::setCoverPropertie()
  {
      QString str, strAlpha, gradient1, gradient2;
      strAlpha.setNum(200);
      gradient1 = "rgba("+str.setNum(cwDisableColor.red())+", "
                  +str.setNum(cwDisableColor.green())
                  +", "+str.setNum(cwDisableColor.blue())
                  +" ," +strAlpha+ " )";
      gradient2 = "rgba("+str.setNum(cwLbColor.red())+", "
                  +str.setNum(cwLbColor.green())+", "
                  +str.setNum(cwLbColor.blue())+" ," +strAlpha+ " )";
  
      QStackedLayout *stackedLayout = new QStackedLayout(this);
      frameCover  = new QFrame(this);     
      frameCover-&gt;setGeometry(rect());
      frameCover-&gt;setStyleSheet("QFrame{border:5px solid  "+strLbColor+"; "
                                    "border-radius: 10px; background-color: "
                                    "qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.5, stop: 0 "
                                    +gradient1+" , stop: 1 "+gradient2+"); }");
  
      stackedLayout-&gt;addWidget(frameCover);
      stackedLayout-&gt;setStackingMode(QStackedLayout::StackAll);
  }
  
  void CQFrame::setCover(bool state)
  {
      frameCover-&gt;setVisible(curCover = state);
  }
  
  void CQFrame::resizeEvent(QResizeEvent *event)
  {
      if (curCover)
          frameCover-&gt;setGeometry(rect());
  }
  </code></pre>
  
  <p>The design isn't mine, I was asked to fix strange visual glitches it experiences.  This "frame" is used in Qt designer as one of widgets. After a while suddenly everything resizes, which prompted question "what is wrong with this code". Qt  fires warning about attempt to add layout while one already exist: I suppose  <em>that</em> may cause a problem, because a frame must have only one layout at time? Code generated by Qt Creator looks something like</p>
  
  <pre><code>void setupUi(CQFrame *CQWnd1T2SeparateONForm)
      {
          if (CQWnd1T2SeparateONForm-&gt;objectName().isEmpty())
              CQWnd1T2SeparateONForm-&gt;setObjectName(QString::fromUtf8("CQWnd1T2SeparateONForm"));
          CQWnd1T2SeparateONForm-&gt;resize(735, 241);
          QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
          sizePolicy.setHorizontalStretch(0);
          sizePolicy.setVerticalStretch(0);
          sizePolicy.setHeightForWidth(CQWnd1T2SeparateONForm-&gt;sizePolicy().hasHeightForWidth());
          CQWnd1T2SeparateONForm-&gt;setSizePolicy(sizePolicy);
          gridLayout = new QGridLayout(CQWnd1T2SeparateONForm); // warning here
  }
  </code></pre>
  
  <p>There is similar problem with standard QMainWindow which always got own "special" layout, which Qt Creator solves  automatically, by adding a central widget to the layout  and everything else is added to that widget. What I don't know that is how to simulate same behavior with a custom widget with Qt Creator plugin.
  Or what alternative design for CQFrame can be used. CQFrame reused in dozen project, in about 30+ panels, so reuse of code for them all is a strict requirement.
  Current plugin is very basic:</p>
  
  <pre><code>class QDESIGNER_WIDGET_EXPORT CQFramePlugin : public QObject,
                               public QDesignerCustomWidgetInterface
  {
      Q_OBJECT
      Q_INTERFACES(QDesignerCustomWidgetInterface)
  
  public:
      CQFramePlugin(QObject *parent = 0);
  
      bool isContainer() const;
      bool isInitialized() const;
      QIcon icon() const;
      QString domXml() const;
      QString group() const;
      QString includeFile() const;
      QString name() const;
      QString toolTip() const;
      QString whatsThis() const;
      QWidget *createWidget(QWidget *parent);
      void initialize(QDesignerFormEditorInterface *core);
  
  private:
      bool initialized;
  };
  </code></pre>
  
  <p>.cpp for it: </p>
  
  <pre><code>#include "cqframe.h"
  #include "cqframeplugin.h"
  
  #include &lt;QtPlugin&gt;
  
  CQFramePlugin::CQFramePlugin(QObject *parent)
      : QObject(parent)
  {
      initialized = false;
  }
  
  void CQFramePlugin::initialize(QDesignerFormEditorInterface * /* core */)
  {
      if (initialized)
          return;
  
      initialized = true;
  }
  
  bool CQFramePlugin::isInitialized() const
  {
      return initialized;
  }
  
  QWidget *CQFramePlugin::createWidget(QWidget *parent)
  {
      return new CQFrame(parent);
  }
  
  QString CQFramePlugin::name() const
  {
      return "CQFrame";
  }
  
  QString CQFramePlugin::group() const
  {
      return "CustomWidgets";
  }
  
  QIcon CQFramePlugin::icon() const
  {
      return QIcon(":/Resources/frame_icon.png");
  }
  
  QString CQFramePlugin::toolTip() const
  {
      return "";
  }
  
  QString CQFramePlugin::whatsThis() const
  {
      return "";
  }
  
  bool CQFramePlugin::isContainer() const
  {
      return true;
  }
  
  QString CQFramePlugin::domXml() const
  {
      return "&lt;ui language=\"c++\"&gt;\n"
             " &lt;widget class=\"CQFrame\" name=\"Frame\"&gt;\n"
             "  &lt;property name=\"geometry\"&gt;\n"
              "   &lt;rect&gt;\n"
              "    &lt;x&gt;0&lt;/x&gt;\n"
              "    &lt;y&gt;0&lt;/y&gt;\n"
              "    &lt;width&gt;120&lt;/width&gt;\n"
              "    &lt;height&gt;80&lt;/height&gt;\n"
              "   &lt;/rect&gt;\n"
              "  &lt;/property&gt;\n"
             " &lt;/widget&gt;\n"
             "&lt;/ui&gt;";
  }
  
  QString CQFramePlugin::includeFile() const
  {
      return "cqframe.h";
  }
  </code></pre>