Can you add a toolbar to QDialog? - c++

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:
Is it possible to add a toolbar to a QDialog? (also is it possible to do this in Qt Designer?)
If 1. is not possible, how can I make a QMainWindow modal?

You can simply use the setMenuBar function of the layout manager that is installed on your QDialog:
myDialog->layout()->setMenuBar(myMenuBar);

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.
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())
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.).

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

Related

The Qt program runs but the popup window doesn't display anything [duplicate]

I designed a QMainWindow with QtCreator's designer. It consists of the default central widget (a QWidget) which contains a QVBoxLayout with all the other widgets in it. Now everything I want, is that the QVBoxLayout automatically occupies the whole central widgets rectangle space.
How can I do this? I didn't find any usable property neither in the central widgets properties nor the QVBoxLayout's ones.
If you want to do it with code instead of using QtCreator, you could set the layout in a QWidget and then set the QWidget as the central widget of the main window like this:
#include <QtGui>
#include <QWidget>
#include <QHBoxLayout>
#include "mainwindow.h"
MainWindow::MainWindow() {
// Set layout
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(myWidget1);
layout->addWidget(myWidget2);
// Set layout in QWidget
QWidget *window = new QWidget();
window->setLayout(layout);
// Set QWidget as the central layout of the main window
setCentralWidget(window);
}
You don't have to create a QVBoxLayout manually. Just select your central QWidget and press a make-layout button.
Add at least one widget on your MainWindow. Then select your window by clicking on it and click on the VerticalLayout Button at the top of QTCreator. You Vertical Layout is automatically added to the central widget and fills all the surface.
This is already answered, but I personally prefer to keep all control elements and layouts added manually to the form. I do not add controls in the class files, I merely hook up the signals/slots to hide/show widgets relevant to the logic in the class, within the class.
To manually add a layout to any widget you must first add at least one child widget/control. That wasn't totally clear to me and I was trying to add the layout first.

How do I make a QWidget automatically scale vertically to it's contents?

I've made a QT Designer Form called DropDownMenu. Essentially it is just a QWidget with a QVBoxLayout inside of it.
DropDownMenu has a function that pragmatically adds buttons to it.
QPushButton* DropDownMenu::AddButton(
const QString& text)
{
QPushButton* new_button = new QPushButton(text, this);
m_ui->LayoutManager->addWidget(new_button);
return new_button;
}
I then add a QWidget to my MainWindow inside of QT Designer & promote this widget to DropDownMenu. Then I add buttons to this new QWidget using the AddButton function.
The end result looks like this...
I want to make it so the containers scale according to how many buttons or widgets are placed inside of the layout, but they seem to just get squeezed together so that they fit the parents default size.
How can I make it so the parent scales to the size of all it's children?

How to create QToolBar in QWidget?

I am trying to add a QToolBar in a QWidget. But I want its functionality to work as if it was a QMainWindow.
Apparently I can not create QToolBar in a QWidget, and using setAllowedAreas does not work with QWidget : it only works with QMainWindow. Also, my QWidget is in a QMainWindow.
How can I create a QToolBar for my widget?
The allowedAreas property only works when the toolbar is the child of a QMainWindow. You can add the toolbar to a layout, but it won't be movable by the user. You can still relocate it programmatically, however.
To add it to a layout for a fictional class inheriting QWidget:
void SomeWidget::setupWidgetUi()
{
toolLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
//set margins to zero so the toolbar touches the widget's edges
toolLayout->setContentsMargins(0, 0, 0, 0);
toolbar = new QToolBar;
toolLayout->addWidget(toolbar);
//use a different layout for the contents so it has normal margins
contentsLayout = new ...
toolLayout->addLayout(contentsLayout);
//more initialization here
}
Changing the toolbar's orientation requires the additional step of calling setDirection on the toolbarLayout, e.g.:
toolbar->setOrientation(Qt::Vertical);
toolbarLayout->setDirection(QBoxLayout::LeftToRight);
//the toolbar is now on the left side of the widget, oriented vertically
QToolBar is a widget. That's why, you can add a QToolBar to any other widget by calling addWidget for layout or by setting the QToolBar parent to your widget.
As you can see in documentation of QToolBar setAllowedAreas method:
This property holds areas where the toolbar may be placed.
The default is Qt::AllToolBarAreas.
This property only makes sense if the toolbar is in a QMainWindow.
That's why it is impossible to use setAllowedAreas if toolbar is not in QMainWindow.
As far as I know, the only way to properly use the toolbar is with the QMainWindow.
If you want to use the full functionality of the toolbar, create a mainwindow with the window flag Widget. This way you can add it inside some other widget without having it displayed as a new window:
class MyWidget : QMainWindow
{
public:
MyWidget(QWidget *parent);
//...
void addToolbar(QToolBar *toolbar);
private:
QMainWindow *subMW;
}
MyWidget::MyWidget(QWidget *parent)
QMainWindow(parent)
{
subMW = new QMainWindow(this, Qt::Widget);//this is the important part. You will have a mainwindow inside your mainwindow
setCentralWidget(QWidget *parent);
}
void MyWidget::addToolbar(QToolBar *toolbar)
{
subMW->addToolBar(toolbar);
}

Add QTextEdit objects to a QMainWindow

I seem to be having an issue. Objective: I want to dynamically add QTextEdit to a QMainWindow, I have a lot of data I wish to split amongst various QTextEdit objects. I've been looking at centralWidget and did some digging into ui->setupUi(this); generated by the Qt Creator and spotted that the parent for objects of interest was the central widget of the QMainWindow. Thus I've tried something like this:
this->m_vecTextEdits.push_back( new QTextEdit(this->centralWidget()) );
where 'this' is the QMainWindow. I just want to add these QTextEdit to the QMainWindow and later remove them. I also tried new QTextEdit(this) hoping it would appear on the QMainWindow with the properties defined by the objects geometry to no luck.
If I setCentralWidget to be that of the QTextEdit than it works but I don't want the object to consume the entire QMainWindow and restrict access to existing widgets.
So I'm in need of advice of basically how I can add QTextEdit widgets to the existing centralWidget of the QMainWindow and have them appear in the window and also remove.
I wanted to add multiple QTextEdit so I can use a residing QListWidget
(the index property) to switch amongst the many QTextEdit widgets
You could put a QStackedWidget in place of your QTextEdit, and add all the QTextEdits to it.
Only one of the textedits would be visible at all time, but you can switch between them automatically by connecting the signal currentRowChanged(int) of your QListWidget to the slot setCurrentIndex(int) so that the index of the QTextEdit stay the same as the index of the selected item in your list.
The QStackedWidget will replace your container m_vecTextEdits too.
It's not enough to just create the widget objects; you also need to add them to a layout object. Try something like:
QBoxLayout * bl = new QBoxLayout(centralWidget());
QTextEdit * t = new QTextEdit;
bl->addWidget(t);

GtkVBox Qt equivalent

In GTK, I used to have a window to which I gtk_container_add()'d a GtkVBox. Then I could pack widgets I wanted to the GtkVBox to have them appear in the window.
Now I've decided to try out Qt, but I can't seem to figure out how to do this in Qt.
Right now what I've done is create a QMainWindow, but I found that you can only pack one main widget into it, which is obviously quite limiting. So I wanted to create something like the GtkVBox and use that as the main widget and then add other widgets to this box.
What I've found by Googling are however only the Q3VBox widget, which seems to be what I want, but is deprecated, and the QVBoxLayout.
I tried to use the QVBoxLayout, but it tells me that I cannot change the layout of my QMainWindow since it already has a layout.
Edit: Here is how I do it (this is in the constructor):
box = new QVBoxLayout;
setLayout(box)
It compiles fine, but during runtime, it prints on the console:
QWidget::setLayout: Attempting to set QLayout "" on HCGWindow "", which already has a layout
(HCGWindow is my app's window, which is a subclass of QMainWindow)
So, how can I create something similar to a GtkVBox in Qt, and if the solution is the Q3VBox, why is it deprecated and what other thing should I use?
Thanks
In fact, here is the recommended solution provided by the Qt documentation.
You should create a QVBoxLayout and add the widgets you want in it. After that, you set the layout on another empty widget and then you set this widget as the central widget of the QMainWindow subclass. Here is an example in code:
QWidget* widget1 = new QWidget(); // This could be anything subclassing QWidget.
QWidget* widget2 = new QWidget();
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(widget1);
layout->addWidget(widget2);
QWidget* central = new QWidget(); // Only a containing QWidget.
central->setLayout(layout);
this->setCentralWidget(central);
Now, you QMainWindow subclass should have the two QWidgets in it, arranged in a QVBoxLayout.
Note here that I did not give any parent to anyone. You could have done it, but when you call addWidget or setCentralWidget, the ownership of the widget (and the layout) is given to the containing class.
If you read a bit about Qt, you'll know that this allows the parent to destroy his children when he is about to be destroyed itself.
Finally, note that QMainWindow is an exception and, from what I know, is the only class with setCentralWidget as a method. If you attempt to create a QWidget subclass, you will be able to use setLayout (as shown in the example above).
Hope this helps.
Try to create QVBoxLayout instance, add your widgets to it and add (not replace) this layout to main window's layout.
Note, QLayout class has no member addLayout, but subclasses has one.
Firstly you must get and remember classname of main window's layout:
qDebug(this.layout()->objectName);
Then add your QVBoxLayout to window's layout:
dynamic_cast<YourWindowLayoutClass>(
this.layout())->addLayout(your_qvboxlayout_object);
I hope it will work.