set Screen for qDockWidget in QMdiArea in Qt 5 - c++

My App uses a QMdiArea is instantiated in a QMainWindow. Its child windows are QScrollArea. Each of them have QDockWidget as child, instantiated upon creation of the QScrollArea.
The QDockWidget are set as floatable.
In multi GPU and multi screen systems, they do not first show up in the same screen. How can I set them floatable and appear in the same screen as the QMdiArea, since QDockWidget do not have the "setScreen" property?
Here is how I set things up within the QMainWindow:
mdiArea = new QMdiArea;
setCentralWidget(mdiArea);
// ImScrollArea inherits a QScrollArea.
ImScrollArea* dropImScrollArea = new ImScrollArea(urlList);
QMdiSubWindow *newSubWindow = new QMdiSubWindow;
newSubWindow->setWidget(dropImScrollArea);
newSubWindow->setAttribute(Qt::WA_DeleteOnClose);
mdiArea->addSubWindow(newSubWindow);
newSubWindow->show();
addDockWidget(Qt::BottomDockWidgetArea, dropImScrollArea->getDock());
dropImScrollArea->getDock()->setFloating(true);
dropImScrollArea->getDock()->show();
The QDockWidget within the QScrollArea is defined as:
dock = new QDockWidget(windowTitle, this);
dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
dock->setFeatures(QDockWidget::DockWidgetMovable);
dock->setFeatures(QDockWidget::DockWidgetFloatable);
dock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea);

Related

Qt window resize event after resize is done

I have a QtChart in a QDialog and I use a simple QWidget to show it on the screen. I need to resize this hart whenever the dialog window is resized by user.
This is how I add the chart to the dialog (in constructor):
// Setup chart view to show the chart
mChartView = new QChartView(mChart, ui->widget);
mChartView->setParent(this);
mChartView->resize(ui->widget->size());
mChartView->setRenderHint(QPainter::Antialiasing);
I have overrided the resizeEvent of the QDialog in my own dialog:
void CurveDialog::resizeEvent(QResizeEvent *event)
{
mChartView->resize(ui->widget->size());
}
This works, and the chart gets resized...but the problem is it is terribly slow! because it will resize for all the steps that user drags the window corner to resize it!
How can I do the resize only when there resize is done? I wanted to use a timer but this looks like a dirty hack! any better ideas?
Qt provides a layout system to manage the geometries of child widgets within a widget. A layout will arrange the size and the position of each child to ensure that it will take all the available space.
The layout will automatically resize the child widgets when the parent is resized:
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QDialog* dialog = new QDialog();
QVBoxLayout* layoutDialog = new QVBoxLayout(dialog);
QWidget* widget = new QWidget();
QVBoxLayout* layoutWidget = new QVBoxLayout(widget);
layoutDialog->addWidget(widget);
layoutWidget->addWidget(chartView);
dialog->exec();

Change QT layout background

Since QVBoxLayout has no a setStylesheet method, I thought this would made the trick:
QWidget *window = new QWidget(this);
window->setStyleSheet("background-image:url(:/images/sky.jpg);font-size:18px;");
QVBoxLayout * layout = new QVBoxLayout(window);
layout->addWidget(widg1);
layout->addWidget(widg2);
setLayout(layout);
Sadly, only a small rectangle of background image appears, not covering entire window. How could I do it?
You can set stylesheet to the central widget of your main window. In the example you can put window into some other layout.

Qt 'glue' two widgets together

I have two widgets (both QFrames), none of them have any title bar associated with them (which I achieve through setWindowFlags(Qt::FramelessWindowHint)). One of them is a main widget, and the other a sidebar sort of widget, which is supposed to stick to it at its right boundary (its height being approximately 1/4th of the main widget).
I cannot keep them both in a transparent QFrame with static positioning, since the main widget is draggable through its top (since title bar is missing on it, I do it manually by intercepting mousepress/mousemove events and moving it accordingly). The custom drag on the main widget works fine, but when I try to move the sidebar along with, a very obvious visual delay shows up between the two, there are momentary gaps visible between the two while dragging the main widget to the left, or momentary overlapping between the two when dragging the main widget to the right (the sidebar is not draggable, no drag logic is implemented for it).
How do I 'glue' these two widgets together, such that they move together all the time without any delay? I browsed the Qt docs, it may be possible that QDockWidget can help here, but I could not understand how. The main widget here is not a QMainWindow.
Platform - OS X Yosemite, Qt 5.3.1, 32 bit.
You should definitely use QDockWidget here.
Make your "main widget" derive from QMainWindow rather than QFrame (it may not be "obvious" as QMainWindow does not derive from QFrame, but it should not be such a big deal).
Then, encapsulate your second widget within a QDockWidget and dock it in the main widget like that:
// secondWidget being your QFrame based widget
// mainWidget being your "main widget"
QDockWidget* dockingBar = new QDockWidget("My bar", mainWidget );
dockingBar->setWidget( secondWidget );
// dock on left side, change first parameter to dock somewhere else:
mainWidget->addDockWidget( Qt::LeftDockWidgetArea, dockingBar );
An alternative is to create a third widget that would become your top-level widget and use a QLayout to insert your two QFrames in this new one:
QWidget* newTopLevelWidget = new QWidget();
// QHBoxLayout to have mainWidget on the left hand side of secondWidget
// Replace by QVBoxLayout to have mainWidget on top of secondWidget
QLayout* layout = new QHBoxLayout( newTopLevelWidget );
layout->addWidget( mainWidget );
layout->addWidget( secondWidget );

QWidget within scrollarea

I have a QWidget that I want to include within a scroll-area so that when the designated QWidget size is exceeded vertically, the user can scroll up and down to see more.
QWidget renameWidget;
QScrollArea scrollarea.
How do I go about doing this? I set the widget inside the scroll-area on the UI editor but it didn't work.
Any ideas?
Thanks.
Think of QScrollArea as another layout. Add the scroll area to your main widget and put everything else inside it with setWidget().
QScrollArea is QWidget, so you can even use it as a top level widget:
QScrollArea *scrollArea = new QScrollArea();
scrollArea->resize(250, 250);
QWidget *widget = new QWidget(scrollArea);
widget->setBackgroundRole(QPalette::Dark);
widget->resize(200, 200);
scrollArea->setWidget(widget);
scrollArea->show();
QScrollArea provides a scrolling view onto another widget. It is used to display the contents of a child widget within a frame. If the widget exceeds the size of the frame, the view can provide scroll bars so that the entire area of the child widget can be viewed.
An example:
QScrollArea *scrollArea = new QScrollArea(this);
scrollArea->setBackgroundRole(QPalette::Dark);
scrollArea->setWidget(renameWidget);

widget hidden under central widget

With Qt 4.8, I have :
a main window (QMainWindow);
a central widget setCentralWidget(x), x beeing a QLabel that contains an image;
another widget "B": a QLabel that contains an image
My problem is that the widget B is hidden under the central widget. How could I raise the widget B in the foreground ?
I know that B is hidden under the central widget because sometimes when B is placed on the left, and the image of the central widget is small enough, I can see a part of B.
You can use B.raise() in order to increase z-index of B widget.
Raises this widget to the top of the parent widget's stack.
After this call the widget will be visually in front of any overlapping sibling widgets.
You could also attach "B" as a child of the central widget, or a child of widget X. This should then show on top.
QWidget B = new QWidget(x);
Alternatively, use a layout and add that to the central widget, with widgets x and B added to the layout. For example: -
QHBoxLayout* pLayout = new QHBoxLayout();
pLayout->addWidget(B);
pLayout->addWidget(x);
pMainWindow->setCentralWidget(pLayout);