Add QTextEdit objects to a QMainWindow - c++

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);

Related

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?

Promote QWidget to QMainWindow or add QMainWindow to QWidget from Qt Designer

My problem:
I want to customize the way the title bar works and looks for my application.
My idea:
I created a new QWidget form in Qt Designer and added a QWidget to it. I added the following code in constructor:
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::FramelessWindowHint);
QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect();
effect->setBlurRadius(20);
effect->setXOffset(0);
effect->setYOffset(0);
setGraphicsEffect(effect);
which makes the outer widget transparent and adds shadow to my inner widget. From this on I can create a custom title bar widget which I can implement however I want.
This is the result:
My issue
I want to make this usable from the designer as a main window and the QWidget doesn't allow me to add FROM THE DESIGNER tool bars, menu bar and status bar.
What I thought about was adding a QMainWindow widget as a child widget for the outer QWidget(which is transparent and acts as support for my shadow(the shadow is drawn on it)). I did this successfully but only from code:
QMainWindow *centralwidget = new QMainWindow();
centralwidget->setStyleSheet("background-color: lightgray;");
centralwidget->setGeometry(0, 0, 50, 20);
centralwidget->setWindowFlags(Qt::Widget);
this->layout()->addWidget(centralwidget);
QMenuBar *menuBar = new QMenuBar(centralwidget);
menuBar->addAction("Action");
QStatusBar *statusBar = new QStatusBar;
statusBar->showMessage("Status bar here");
centralwidget->addToolBar("tool bar");
centralwidget->setMenuBar(menuBar);
centralwidget->setStatusBar(statusBar);
This is the result:
My question:
How can I achieve this result from Qt Designer? Is it possible to promote a QWidget to QMainWindow? I cannot think to another way of doing it... It is really important for me to make it usable from Qt Designer because I intend to make it a template widget and be able to create e.g. a new QCustomMainWindow form Qt Creator just like you can create a QWidget or a QMainWindow.
Please help!
Here is another SO question similar to yours: Qt4: Placing QMainWindow instance inside other QWidget/QMainWindow
Just adding on to my original comment:
Start with a QMainWindow, and then apply the appropriate flags to it. QMainWindow is a subclass of QWidget. If it can't be done easily in the designer, it is pretty painless to do in code. Do it in your constructor right after the ui->setup() call.
Start with QMainWindow
Customize Window Flags
So in the constructor in mainwindow.cpp, you put
http://qt-project.org/doc/qt-5/qt.html#WindowType-enum
this->setWindowFlags(Qt::Widget);
This is the default type for QWidget. Widgets of this type are child
widgets if they have a parent, and independent windows if they have no
parent. See also Qt::Window and Qt::SubWindow.
// or if you want to apply more than one you, "or" it together, like so:
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool);
Try out a couple of those and see what you like.
Customize Widget Attributes
There are also Widget Attributes, that give you strong control over how your widgets look like and behave.
http://qt-project.org/doc/qt-5/qt.html#WidgetAttribute-enum
Qt Style Sheets
In addition to all the flags and attributes above, you can also modify a ton of it with stylesheets:
http://qt-project.org/doc/qt-5/stylesheet-reference.html
this->setStyleSheet("background: #000000;");
Qt Designer Custom Widgets
And also if you are interested in making this a reusable thing in Qt Designer, you can make it into a Qt Designer plugin, or custom widgets.
http://qt-project.org/doc/qt-4.8/designer-using-custom-widgets.html
http://qt-project.org/doc/qt-4.8/designer-creating-custom-widgets.html
QMdiArea and QMdiWindow
Another path to look into besides using QMainWindow is QMdiSubWindow
http://qt-project.org/doc/qt-5/QMdiSubWindow.html

Can you add a toolbar to QDialog?

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

Can't move QDockWidget

I want to create a widget that contains several QDockWidgets on purpose of putting it into a QMainWindow. Problem is that if I add QDockWidgets to my QWidget class with layout->addWidget(dockWidget);(I don't know any other way of doing it) and then setLayout(layout) I can't do anything to the QDockWidgets but dock and undock. I can't move them, I can't position them in another place.
QMainWindow has this feature addWidgets that QWidget doesn't have. Using QMainWindow everything works perfect, but I want it to work the same if I add a QWidget object(containing some QDockWidgets) to QMainWindow.
Is there any possibility to make my QWidget fully support those QDockWidgets, and use the on full potential(move, scale, dock, change position)?
Thanks
If you're using a lot of QDockWidgets, simply enabling dock nesting might be the solution to the underlying problem.
If you absolutely need to have a widget inside the QMainWindow, you can try putting another QMainWindow in the first one. You might have to set the windowFlags property of the second QMainWindow to Qt::Widget.

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.