Can't move QDockWidget - c++

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.

Related

How disable window move inside an area?

I'm trying to write a circuit designer software in QT on Linux. I'm using KDE 5 Plasma desktop and QTCreator as an IDE.
I tried to use QFrame paintEvent to paint on it, and it worked, but when im grabbed the window inside QFrame it moved.
I know about QGraphicsView, but i cant make a custom class and promote it based on that(it's not listed).
How can i create a custom class from a container(QFrame, QGraphicsView or anything) where i can override paint event and also it doesn't move window if i grab it?
Sorry for my poor english.
QGraphicsView inherits from QAbstractScrollArea which inherits from QFrame itself.
So you can keep the QFrame in the form, and keep it promoted to your canvas class, but simply make you canvas class inherit QGraphicsView instead.
Although, my Qt has two differences in behavior from the OP (but I don't use KDE):
Clicking on a QFrame and moving the mouse doesn't move the whole window for me. I guess this behavior for the OP could be changed by reimplementing void mousePressEvent ( QMouseEvent * event ) in the canvas class and giving it an empty code instead. (doc)
I can put QGraphicsView in my ui files, and I can right click on them to promote them to another custom-defined class.
Edit: Found the reason why the window moves on KDE!

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

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.

How do i cause a qtabwidget instance to automatically resize when child tabs are added to it?

I am trying to get the QTabWidget automatically resized to fit the child tab when the child is added but have been unable to do so. I have created a form using Qt Designer and have inherited this using the single inheritance approach as follows.
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = 0);
private:
Ui::MyForm ui;
};
I have a QTabWidget and I am adding the instance of the object to my QTabWidget using the addTab(). When I display the QTabWidget, I notice that it hasn't resized to fit the MyWidget instance. What do I need to do to ensure that the QTabWidget instance gets automatically resized?
In designer, make sure you add a layout to your widget. Click on the widget's background so that way when you apply a layout, it applies to the whole widget. The trick is that the base (parent) widget that your form is built on needs a layout, and not just the items in the form.
Grid's are generally pretty easy to use. But sometimes the other ones are better. Designer can be tricky to use and takes a while to get used to. Basically every widget should probably have a layout applied to it. Strange things can happen when you don't.
I believe this is a bug of the Creator (at least for V4.7.4 opensource).
My solution is as following.
Do not create the QTabWidget object in the main project.
Create it independently (by creating Qt-> Form-class).
Then, copy the 3 files (.h, ,cpp, .ui) into the project, and add them to the project.
The result is: it resizes as the mainwindow resizing.
To fit any widget into its parent widget, you need to use a particular layout (grid, horizontal, vertical etc).