Display window full screen on secondary monitor using Qt - qt

Seems to be possible with native controls (see here and here) so now I'm looking for some Qt code to do it.

I use this code for the second display in full screen successfully on both Windows & Linux
QRect screenres = QApplication::desktop()->screenGeometry(1/*screenNumber*/);
SecondDisplay secondDisplay = new SecondDisplay(); // Use your QWidget
secondDisplay->move(QPoint(screenres.x(), screenres.y()));
secondDisplay->resize(screenres.width(), screenres.height());
secondDisplay->showFullScreen();

One way of doing it in Qt5 is to use QWindow::setScreen to set the screen on which the window should be shown. QWidget has a windowHandle() that returns the pointer to the QWindow.
Here is how to show your widget on second screen in full-screen mode :
QWidget * widget = new QWidget();
widget->show();
widget->windowHandle()->setScreen(qApp->screens()[1]);
widget->showFullScreen();

My take on this:
auto const desktop(QApplication::desktop());
setGeometry(desktop->screenGeometry(1));
#ifndef Q_OS_WIN
setWindowState(Qt::WindowState(Qt::WindowFullScreen | windowState()));
#endif // Q_OS_WIN

showFullScreen first, then setGeometry.
Qt5 tested OK

This problem got solved while using window->showFullScreen() instead of window->show().

Related

QDockWidget with QStatusBar possible?

For a QMainWindow I can easily set a status bar. When I have a floating QDockWidget, it behaves like a normal window (from user's perspective).
What I want to archive is to add a QStatusBarto the floating QDockWidget. With the signal topLevelChanged I could hide the status bar when the window is docked.
But can I add a status bar to a QDockWidget? At least in the Qt Creator form builder I can not (I have a context menu "Create Status Bar" for QMainWindow, but not for QDockWidget).
Any way to do it a runtime?
Just do this:
QStatusBar *bar = new QStatusBar;//in constructor for example
bar->showMessage(tr("Ready"));
ui->dockWidget->setWidget(bar);
In this case QStatusBar will be as widget, but you can also use some QWidget as container and add layout where your QStatusBar will be always bottom.
With QProgressBar:
QStatusBar *bar = new QStatusBar;
QProgressBar *pr = new QProgressBar;
bar->showMessage(tr("Ready"));
pr->setValue(50);
bar->addPermanentWidget(pr);
ui->dockWidget->setWidget(bar);
Result(there is "Ready" too, but you can't see it because of size of my window) :
Little example with another part of your question:
QStatusBar *bar = new QStatusBar;
QProgressBar *pr = new QProgressBar;
bar->showMessage(tr("Ready"));
pr->setValue(50);
bar->addPermanentWidget(pr);
ui->dockWidget->setWidget(bar);
connect( ui->dockWidget,&QDockWidget::topLevelChanged,[=](bool visible)
{
if(visible)
bar->hide();
else
bar->show();
});
I used here C++11 (CONFIG += c++11 to .pro file) and new syntax of signals and slots, but of course you can use old syntax if you want.

QT - Resize QToolbar

i have some concatenate toolbar. For every toolbar i have call:
toolbar->setGeometry(x,y,width,height)
but i have no resize.
I try to call
toolbar->updateGeometry();
but nothing.
My goal is to expand every toolbar with my size definition
There is a good chance you are using this for repositioning your toolbars on init and saving at closing.
Here is a solid way to do that:
What you really need is to use the QMainWindow saveGeometry() and restoreGeometry() functions and save and load the byte array through the QSettings interface.
writeSettings
QSettings s;
s.beginGroup("MainWindow");
this->restoreGeometry(s.value("geometry").toByteArray());
this->restoreState(s.value("windowState").toByteArray());
s.endGroup();
readSettings
QSettings s;
s.beginGroup("MainWindow");
s.setValue("geometry", saveGeometry());
s.setValue("windowState", saveState());
s.endGroup();
Hope that helps.
You can try QWidget::resize( int w, int h ) to resize the toolbar.
toolbar-> resize( 200, 20 );
The toolbar's geometry is either managed by a layout or by the main window.
You'd need to show how is the toolbar used/displayed.

Custom Qt designer widget : a scroll Area containing a custom vertical layout

I want to do something fairly simple : add a custom widget to Qt designer that would basically be a scrollArea containing a custom vertical layout(I added some code to the vertical layout in order to handle its objects for my projects).
The idea would be to represent a vertical menu that would be on the side of my screen
What I have done so far
I created the custom widget plugin and my custom layout.
My custom widget codes looks like this:
#include "menuwidget.h"
MenuWidget::MenuWidget(QWidget *parent) :
QScrollArea(parent)
{
this->setWidgetResizable(true);
QWidget* layoutHoldingWidget= new QWidget(this);
layout= new MenuLayout();
layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
layout->addStretch(1);
layoutHoldingWidget->setLayout(layout);
this->setWidget(layoutHoldingWidget);
}
If I add manually to the layout (in the constructor code) some buttons
for(int i =0;i<20;i++)
layout->addWidget(new QPushButton(this));
It does work and I can see my scrollArea containing some buttons, which is almost what I want.
What I want
I would like to be able to add these buttons directly via Qt designer: the user would first drag the empty MenuWidget on the main window, then would drag QPushButtons on my custom widget exactly like he would do on a regular vertical layout.
Is that possible?How could I do such a thing?
Thank you ! :)
Edit 1
What I was missing was the "scrollAreaWidgetContents" widget that is always created when you drag and drop a QScrollArea. I did a similar thing by adding a widget (let's call it containerWidget) to my custom scrollArea in its domXml function, which enables me to drag and drop widgets on my scroll Area like I wanted to do.
BUT there's still something I can't figure out : I want the containerWidget to have a customLayout (myCustomLayout) . If I add it in the domXml function, I get the following line in the terminal :
Designer:The layout type 'MyCustomLayout' is not supported,
defaulting to grid.
So it means that I can't tell designer to use my custom layout to place my widgets, which is kind of sad :D
Is there any way to "cheat" here?
There are two things to consider:
1) Overwrite in the class you derive from QDesignerCustomWidgetInterface the function to return true
bool isContainer() const { return true; }
This tells QtDesigner that the widget can contain children. (In Qt nearly any Widget can contain any widget as child, but QtDesigner tries to restrict it in a sensible way - e.g. you cant add children to a QLabel in QtDesigner)
2) Implement childEvent of your Widget. Probably in your case it would add Widgets added in QtDesigner to a layout.
Here is a core I've implemented to try this out. I've created a skeleton using "Qt Widget Plugin" Wizard in QtCreator and modified a little bit.
Don't forget to build as release, for the compiler/Qt-version of your QtDesigner , to copy the .dll and .lib files in \plugins\designer directory and to restart QtDesigner!
verticalplugin.cpp
//all other functions remained as created by QtCreator wizard
bool VerticalMenuPlugin::isContainer() const
{
return true;
}
VerticalMenu.h
#ifndef VERTICALMENU_H
#define VERTICALMENU_H
#include <QtGui/QWidget>
#include <QtGui/QVBoxLayout>
class VerticalMenu : public QWidget
{
Q_OBJECT
protected:
virtual void childEvent ( QChildEvent * event );
public:
VerticalMenu(QWidget *parent = 0);
};
#endif
VerticalMenu.cpp
#include "verticalmenu.h"
#include <QChildEvent>
VerticalMenu::VerticalMenu(QWidget *parent) :
QWidget(parent)
{
setLayout (new QVBoxLayout);
}
void VerticalMenu::childEvent ( QChildEvent * event )
{
if ( event->added() )
{
QWidget * newChild = qobject_cast<QWidget *>(event->child());
if ( newChild )
{
layout()->addWidget( newChild );
}
}
}
I hope' it would help as a starting point.
Qt 4 does not support custom layout plugins for designer, so I couldn't achieve what I wanted to do. I will instead use a Vertical Layout and try to implement the additional features that were supposed to be in the custom layout code in the widget code.

Qt: Set size of QMainWindow

I'm new to Qt, so I wonder whether there is a way to set the size of a QMainWindow to (for example) 70% of the user's desktop.I tried the stretch factor but it didn't work. QWidget::setFixedSize worked but only with a pixel number, I think.
Somewhere in your QMainWindow constructor, do this:
resize(QDesktopWidget().availableGeometry(this).size() * 0.7);
This will resize the window to 70% of the available screen space.
Thanks to Amir eas. The problem is solved. Here's the code for it:
#include <QDesktopWidget>
#include <QMainWindow>
...
QDesktopWidget dw;
MainWindow w;
...
int x=dw.width()*0.7;
int y=dw.height()*0.7;
w.setFixedSize(x,y);
You can use the availableGeometry(QWidget*) method in QDesktopWidget, this will give you the geometry of the screen that this widget is currently on. For example:
QRect screenSize = desktop.availableGeometry(this);
this->setFixedSize(QSize(screenSize.width * 0.7f, screenSize.height * 0.7f));
Where this is the MainWindow pointer.
This will work when using multiple screens.
Just to update #muesli's answer for Qt6, QDesktopWidget had been deprecated in Qt5 and in Qt6 is removed.
The new equivalent code is
resize(QGuiApplication::primaryScreen()->availableGeometry().size() * 0.7);

screenshot of a qt application from inside the application

I am trying to capture a screenshot of my application within the application. Its a Qt-based application. Is anyone aware of how to do this? Any suggestions are very welcome.
CV
You can tell any QWidget (including your QMainWindow) to render itself off-screen:
http://developer.qt.nokia.com/doc/qt-4.8/qwidget.html#render
Technically this is not a screenshot as it renders the widget explicitely for this purpose instead of capturing what is seen on-screen. For almost any purpose it doesn't matter.
If you have a GL widget, you can/must instead use grabFramebuffer() which has the advantage of capturing what is seen on the screen.
With this example you could get all your widget screen.
You could attach this method to any key press or signal, as you prefer, to get successive screenshot.
MyClass::screenshot()
{
QWidget *w = QApplication::activeWindow();
if(w) {
static int count = 0;
QPixmap p = QPixmap::grabWidget(w);
p.save(QString("/your/path/screenshot%1.png").arg(count));
count++;
}
}
QPixmap lets you do a window grab if you have the ID. My references are for PyQt but I'm sure you can make the adjustments:
How to get RGB values of QPixmap or QImage pixel - Qt, PyQt
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qpixmap.html#grabWindow
In modern QT 5+ it can be done like that:
void MainWindow::takeScreenshot(const QString screenshotFileName)
{
if(isActiveWindow())
{
auto grabbedScreenshot = QWidget::grab();
grabbedScreenshot.save(screenshotFileName);
}
}

Resources