14

I'm working on a project that needs to call a modal window with a toolbar to do some work on some data before it's loaded. The reason I need the toolbar is the user has a few different possible options that can be combined.

The obvious choice here is a Modal dialog (which I have working right now). The issue is I want a toolbar. This is a two part question:

  1. Is it possible to add a toolbar to a QDialog? (also is it possible to do this in Qt Designer?)
  2. If 1. is not possible, how can I make a QMainWindow modal?
Boris Dalstein
  • 7,015
  • 4
  • 30
  • 59
John
  • 347
  • 1
  • 7
  • 14

3 Answers3

27

You can simply use the setMenuBar function of the layout manager that is installed on your QDialog:

myDialog->layout()->setMenuBar(myMenuBar);
Fred
  • 902
  • 9
  • 12
6

If you don't need the built-in drag and drop feature of QMainWindow's toolbars, you can simply add a QToolBar to any layout, including QDialog's layout(). See the DigviJay Patil's answer below for details, which is definitely cleaner conceptually.

Otherwise, please read on.


  1. It is not directly possible to add a QToolBar to a QDialog in the QMainWindow::addToolBar() sense, because QDialog inherits only QWidget and not QMainWindow, as you noted (hence do not have the method addToolBar())

  2. You can't make a QMainWindow modal, but you can insert a QMainWindow in a QDialog this way:

Code:

MyDialog::MyDialog() :
    QDialog()
{
    QMainWindow * mainWindow = new QMainWindow(); // or your own class
                                                  // inheriting QMainWindow

    QToolBar * myToolBar = new QToolBar();
    mainWindow->addToolBar(myToolBar);

    QHBoxLayout * layout = new QHBoxLayout();
    layout->addWidget(mainWindow);
    setLayout(layout);
}

Indeed, a QMainWindow doesn't necessarily have to be a top-level widget, and you can even insert several QMainWindows as children of a single widget (may not be the wisest choice though, as the user would probably be confused with the separate sets of menu bars, toolbars, dock widgets, etc.).

Boris Dalstein
  • 7,015
  • 4
  • 30
  • 59
  • 1
    The next question would have to be: is this best practice in my situation? I assume I'm going to have to hand-build the Qmainwindow without the convenience of Qt designer right? – John Aug 26 '13 at 03:22
  • 1
    I've never used Qt Designer: isn't it possible to graphically insert a QMainWindow inside another widget? Anyway, another option is to use a vertical layout with two widgets: on top your QToolBar, and on bottom whatever you wanted as a "central widget". Again, This is doable for sure manually, but maybe Qt Designer prevents the possibility to use a QToolBar outside a QMainWindow. But be careful, from the documentation: `When a QToolBar is not a child of a QMainWindow, it loses the ability to populate the extension pop up with widgets added to the toolbar using addWidget().` – Boris Dalstein Aug 26 '13 at 04:04
  • This worked, had to remove and stuff to get it to look right but that seems to be quick. Thanks. – John Aug 26 '13 at 04:48
  • I implemented the solution and it works, but now user can move the toolbar from top to left, right or bottom of the dialog window. Is there a way to fix the position of toolbar in this example? Edit: Solution to above question is: myToolBar->setMovable(false); Yet i have another question: if we use toolbar in main window, it clings to the top and seems well. But in this solution, I could not find a way to cling the toolbar/layout to the window. Is there a way? – meakgoz Sep 29 '15 at 09:24
  • BE CAREFUL! Your mainWindow has not any parent. You will have memory leak when the dialog is deleted. The instruction layout->addWidget(mainWindow) does NOT set ownership. You should do a mainWindow.setParent(this) – pablo_worker Feb 21 '17 at 12:37
  • 2
    @pablo_worker I think you are incorrect. `layout->addWidget()` does not set ownership right away, but `setLayout` should. See http://doc.qt.io/qt-4.8/layout.html. `The layout will automatically reparent the widgets (using QWidget::setParent()) so that they are children of the widget on which the layout is installed` – Boris Dalstein Feb 21 '17 at 19:23
  • 2
    I looked at Qt 4.8 source code, [setLayout()](https://github.com/qt/qt/blob/4.8/src/gui/kernel/qwidget.cpp#L9809) does indeed the job of parenting. The relevant call is `l->d_func()->reparentChildWidgets(this);`, where the function reparentChildWidgets is defined [here](https://github.com/qt/qt/blob/0a2f2382541424726168804be2c90b91381608c6/src/gui/kernel/qlayout.cpp#L957). – Boris Dalstein Feb 21 '17 at 19:32
  • **This is demonstrably awful.** While `QMainWindow` *does* subclass `QWidget` and is thus generically reusable as a standard widget, doing so is extreme overkill in all possible use cases (including this one), is aesthetically unappealing without significant manual intervention, *and* invites subtle issues relating to the fact that a `QMainWindow` embedded within another `QWidget` is no longer a main window at all. Instead, see *any* of the other answers below – all of which are blatantly superior. This should *not* be the accepted answer. – Cecil Curry Feb 28 '18 at 04:59
  • @CecilCurry Thanks for your comment :) I do agree with oversight (this answer of mine is 5 years old now) that the solution I proposed here is overkill in many situations, and that I'd use DigviJay Patil's solution myself in some situations. I edited my answer to reflect this. However, I'd still not qualify my answer as "demonstrably awful". It works perfectly fine, and there are only two other answers: one is irrelevant (menubars instead of toolbars), and the other does not provide as much functionality. Therefore, it is not blatantly superior IMHO; it just has different pros and cons. – Boris Dalstein Mar 08 '18 at 16:35
6

You can add QToolBar in QDialog. But as a QWidget. Please have a look

MyDialog::MyDialog(QWidget *parent) : QDialog(parent)
{
   QVBoxLayout *mainLayout = new QVBoxLayout(this);

   QToolBar *toolBar = new QToolBar();
   mainLayout->addWidget(toolBar);

   QAction *action1 = new QAction("Add", toolBar);
   QAction *action1 = new QAction("Del", toolBar);

  //Add What you want
}

As QToolBar is child of QWidget we can add it as Widget. Using Layout you can adjust its position. Please check this link http://developer.nokia.com/community/wiki/How_to_use_QToolBar_and_QToolButton_in_Qt

DigviJay Patil
  • 986
  • 14
  • 31