How to center a QMainWindow - c++

I'm using Qt but I don't know how to center a QMainWindow window. I wrote this code, but it doesn't works. Thanks in advance.
QRect screenGeometry = QApplication::desktop()->screenGeometry();
int x = (screenGeometry.width() - w->width()) / 2;
int y = (screenGeometry.height() - w->height()) / 2;
w->move(x, y); // w is a QMainWindow pointer
I get this:

These functions are obsolete:
QApplication::desktop()->screenGeometry()
QApplication::desktop()->availableGeometry()
QDesktopWidget::screen()
Use QScreen instead:
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QScreen>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
move(screen()->geometry().center() - frameGeometry().center());
}

the following code works in the latest version of Qt 6.4.1
#include <QApplication>
#include <QScreen>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
int width = w.frameGeometry().width();
int height = w.frameGeometry().height();
QScreen *screen = a.primaryScreen();
int screenWidth = screen->geometry().width();
int screenHeight = screen->geometry().height();
w.setGeometry((screenWidth/2)-(width/2), (screenHeight/2)-(height/2), width, height);
w.show();
return a.exec();
}

Thank you to everybody. I already solved my problem, using this code.
w->setFixedSize(400, 400);
int width = w->frameGeometry().width();
int height = w->frameGeometry().height();
QDesktopWidget wid;
int screenWidth = wid.screen()->width();
int screenHeight = wid.screen()->height();
w->setGeometry((screenWidth/2)-(width/2),(screenHeight/2)-(height/2),width,height);
w->show();
I get this:

There's a shorter solution I saw somewhere:
show();
move(
QApplication::desktop()->screen()->rect().center()
- frameGeometry().center()
);
Yet, for some weird reason, the window still does not appear exactly at the center.

Related

Fix the Qt application orientation to landscape

Developing a tablet based qt application in windows platform. As per our requirement need to fix the application to landscape mode but not able to fix that. We were using QMainWindow.
Referred few links to fix the issue but didn't worked.
Reference1 , Reference2 : Tried by overriding functions.
Reference3 : Also tried this in our qt application, but not worked.
Below code is our sample code:
mainwindow.h
#include <QMainWindow>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
int heightForWidth(int w) const;
QSize sizeHint() const;
private:
Ui::MainWindow *ui;
};
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QVBoxLayout>
#include <QDebug>
#include "windows.h"
#include "qt_windows.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// typedef BOOL (WINAPI* SETAUTOROTATION)(BOOL bEnable);
// SETAUTOROTATION SetAutoRotation = (SETAUTOROTATION)GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
// (LPCSTR)2507);
// if (SetAutoRotation != nullptr)
// {
// qDebug() << "bEnable: " << SetAutoRotation;
// SetAutoRotation(FALSE);
// }
// qDebug() << "bEnable: " << SetAutoRotation;
MainWindow w;
w.showMaximized();
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "windows.h"
#include "qt_windows.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QSizePolicy currPolicy = this->sizePolicy();
currPolicy.setHeightForWidth(true);
this->setSizePolicy(currPolicy);
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
int MainWindow::heightForWidth(int w) const
{
return (w * 240 )/320;
}
QSize MainWindow::sizeHint() const
{
int w = 1366;
return QSize(w, heightForWidth(w) );
}
Can anyone help me on fixing this. Please let me know if am doing anything wrong in above code.
Had the same problem and unfortunately, the best solution was just to disable rotation in Windows settings. I doubt there is a reasonable way to do that from application but i'am not 100% sure.
Only other solution i found was to draw your view according to Windows rotation (so the view would be drawn rotated).
Here is how to read Windows current rotation.

Qt5 - why not screenshot and saving to a file?

Why its not saving any file?
#include "mainwindow.h"
#include <QApplication>
#include <QPixmap>
#include <QPainter>
#include <QList>
#include <QScreen>
QPixmap grabScreens() {
auto screens = QGuiApplication::screens();
QList<QPixmap> scrs;
int w = 0, h = 0, p = 0;
foreach (auto scr, screens) {
QPixmap pix = scr->grabWindow(0);
w += pix.width();
if (h < pix.height()) h = pix.height();
scrs << pix;
}
QPixmap final(w, h);
QPainter painter(&final);
final.fill(Qt::black);
foreach (auto scr, scrs) {
painter.drawPixmap(QPoint(p, 0), scr);
p += scr.width();
}
return final;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPixmap pixmap = grabScreens();
QFile file("file.jpg");
file.open(QIODevice::WriteOnly);
pixmap.save(&file, "JPG", 1);
MainWindow w;
w.show();
return a.exec();
}
The file you're looking for should be in the same folder of the executable.
If you're running your code from Qtcreator, it should be in the build directory, as specified in the Build Settings of the Projects page.
You should consider using QStandardPaths to query for a writable location for the screenshot to be saved to. This will avoid the issue of trying to write to a read-only directory.

QPushButton in a sub-QMenu, change background on hover

EDIT:
NOTE this only occurs when the button is in a SUBMENU. (Menu in a menu.) This code works fine only on the parent menu!
Running Qt 5.0.2, on Windows 7. I have a QMenu with a QWidgetAction in it. Inside the QWidgetAction is a QPushButton. I would like to change the background color of the button when the mouse hovers over it.
Here is my code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMenu>
#include <QWidgetAction>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QMenu menu;
QMenu *subMenu = new QMenu("SubMenu text");
QWidgetAction *widgetAction = new QWidgetAction(subMenu);
QPushButton *btn = new QPushButton("test");
btn->setStyleSheet("QPushButton:hover{background-color: #ff0000;}");
widgetAction->setDefaultWidget(btn);
subMenu->addAction(widgetAction);
menu.addMenu(subMenu);
menu.exec();
}
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
However when the cursor hovers over the QPushButton the background color doesn't change. Doesn't matter if I run it in fusion style or not.
What is going on here? Thanks for your time.
This sound like mouseTracking is not enabled on the widget (and/or probably on the parent widget(s)). You can enable it by calling
QWidget::setMouseTracking(bool enable);
Background may not be customized, if you don't change a border style of a button.
How to solve: use some non-default style, for example:
const auto fusion = QStyleFactory::create( "Fusion" );
QApplication::setStyle( fusion );
QPushButton is not designed for perfect handling hover events. For example, hover event will not change a font via stylesheet.
How to solve: use QToolButton instead.
P.S. Don't know, why it's not worked for you. Everything is OK for me...
UPDATE
Just copy-paste it and run:
#include <QApplication>
#include <QWidgetAction>
#include <QMenu>
#include <QPushButton>
#include <QToolButton>
#include <QStyleFactory>
void showMenu()
{
const auto parent = qApp->activeWindow();
auto menu = new QMenu( parent );
auto root = new QMenu( "Root", menu );
menu->addMenu( root );
auto wa = new QWidgetAction( parent );
auto tb = new QToolButton;
tb->setText( "ToolBtn" );
wa->setDefaultWidget( tb );
root->addAction( wa );
menu->exec( QCursor::pos() );
menu->deleteLater();
}
int main(int argc, char *argv[])
{
QApplication a( argc, argv );
const auto fusion = QStyleFactory::create( "Fusion" );
const auto qss =
"QToolButton:!hover{background-color: #00ff00;}"
"QToolButton:hover{background-color: #ff0000;}"
;
QApplication::setStyle( fusion );
qApp->setStyleSheet( qss );
QWidget w;
w.resize( 800, 600 );
auto btn = new QPushButton{ "Test", &w };
QObject::connect( btn, &QPushButton::clicked, &showMenu );
w.show();
return a.exec();
}

Set icon to custom QFontDialog

I created my own font dialog from QFontDialog (new SLOT added). After that, I can't set icon (*.png) to my new font dialog (with func. setWindowIcon). If I use setWindowIcon to default QFontDialog - everything is OK. So, how to set icon to my new font dialog?
FontDialog.h
#include <QtGui>
#include <QtCore>
class FontDialog: public QFontDialog {
public:
FontDialog();
~FontDialog();
public slots:
void someSlot(void);
};
FontDialog.cpp
#include "FontDialog.h"
FontDialog::FontDialog() {
}
FontDialog::~FontDialog() {
}
void someSlot(void) {
}
main.cpp
#include "FontDialog.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
FontDialog *fontDialog = new FontDialog();
fontDialog->setWindowIcon(QIcon(".//icon.png")); // !!!NOT WORKING!!! for custom QFontDialog
fontDialog->show();
app.exec();
}
I'm using Qt 4.8.5 with Qt Designer 2.7.1 environment.
Thanks for any help.
The below works under Qt 4.8.4 on both OS X and Windows 7. It also works on 5.1.1 on Windows, but not on OS X :(
#include <QFontDialog>
#include <QApplication>
#include <QIcon>
#include <QPainter>
class Dialog : public QFontDialog {
public:
Dialog(QWidget *parent = 0) : QFontDialog(parent) {}
Dialog(const QFont & initial, QWidget *parent = 0) : QFontDialog(initial, parent) {}
};
QIcon myIcon(const QColor & color)
{
QIcon icon;
QPixmap pm(128, 128);
pm.fill(Qt::transparent);
QPainter p(&pm);
p.translate(64, 64);
p.scale(50, 50);
p.setBrush(color);
p.setPen(QPen(Qt::lightGray, 0.1));
p.drawEllipse(-1, -1, 2, 2);
icon.addPixmap(pm);
return icon;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setWindowIcon(myIcon(Qt::red));
Dialog d;
d.setWindowIcon(myIcon(Qt::blue));
d.show();
return a.exec();
}

Fastest code changing pixels in Qt for animation

I want to animate small (100x20) image by changing the color of its pixels by the same value. For example, increase red-channel value by 1 every frame and then decrease back. The image has alpha channel, the animation speed is 30...100 fps (platform dependent; 30 is enough for linux, but windows requires ~70 to look smooth).
As i know, drawing is faster when done in QImage, but displaying is faster with QPixmap.
I like QGraphicsEffects, and QPropertyAnimations. White doesn't colorize, but black does.
#include <QLabel>
#include <QPixmap>
#include <QGraphicsColorizeEffect>
#include <QTimerEvent>
#include <QPropertyAnimation>
#include <QShowEvent>
#include <QDebug>
class Widget : public QLabel
{
Q_OBJECT
Q_PROPERTY(qreal redness READ getRedness WRITE setRedness)
public:
Widget(QWidget *parent = 0)
{
QPixmap p(300, 300);
p.fill(Qt::black);
this->setPixmap(p);
colorize = new QGraphicsColorizeEffect();
colorize->setColor(Qt::red);
redness = 0;
colorize->setStrength(redness);
this->setGraphicsEffect(colorize);
animation = new QPropertyAnimation(this,"redness");
animation->setDuration(2000);
animation->setLoopCount(10);
animation->setStartValue(0.0);
animation->setEndValue(1.0);
animation->setEasingCurve(QEasingCurve::CosineCurve);
animation->start();
}
~Widget(){}
qreal getRedness()
{
return redness;
}
void setRedness(qreal val)
{
redness = val;
colorize->setStrength(redness);
this->update();
// qDebug() << redness;
}
public slots:
void showEvent(QShowEvent *)
{
animation->start();
}
private:
qreal redness;
QGraphicsColorizeEffect * colorize;
QPropertyAnimation * animation;
};
and here is the main.cpp
#include <QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Hope that helps.