I want a resize feature in a QWidget using Qt, like the one shown in the image below.
I have used following tried following ways:
using QSizeGrip, setSizeGripEnabled
For completeness I'm showing two examples: with and without the Qt Designer.
Example using Qt Designer
Check the sizeGripEnabled property:
Preview from within the Qt Designer (Form > Preview...):
Minimal application to show the dialog:
#include <QtWidgets/QApplication>
#include <QDialog>
#include "ui_DialogButtonBottom.h"
class Dialog : public QDialog {
public:
Dialog(QWidget* parent = nullptr) :
QDialog(parent) {
ui.setupUi(this);
}
private:
Ui::Dialog ui;
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Dialog dlg;
return dlg.exec();
}
Resut
Without Qt Designer
#include <QtWidgets/QApplication>
#include <QDialog>
class Dialog : public QDialog {
public:
Dialog(QWidget* parent = nullptr) :
QDialog(parent) {
setWindowTitle("Example");
setSizeGripEnabled(true);
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Dialog dlg;
return dlg.exec();
}
Result
Update to include Frameless mode
Adding the Frameless windows hint doesn't change anything: it works correctly. Obviously, there is no frame so resize/move methods provided by the windows manager are not available.
#include <QtWidgets/QApplication>
#include <QDialog>
class Dialog : public QDialog {
public:
Dialog(QWidget* parent = nullptr, Qt::WindowFlags flags = 0) :
QDialog(parent, flags) {
setWindowTitle("Example");
setSizeGripEnabled(true);
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Dialog dlg(nullptr, Qt::FramelessWindowHint); // frameless
return dlg.exec();
}
Result
As all the options are working straightforwardly, I'd suggest you to carefully review your code/UI design for things like setting a maximum/minimum size (if both are the same, the grip will still be available but won't change the size at all).
Related
I'd like my project to be written programmatically instead of using Qt Designer.
EDIT:
I'm just asking for a template :P
This requirement has a very simple solution: Just do write your code programatically instead of using QtDesigner. :)
EDIT 2: I found out how, feel free to use the code down below:
#include <QtWidgets/QDialog>
#include <QtWidgets/QApplication>
class MyWindow : public QDialog {
public:
MyWindow(QWidget* parent = nullptr);
};
MyWindow::MyWindow(QWidget* parent)
: QDialog(parent)
{
setWindowTitle("MyWindow");
// Make widgets, etc...
}
int main(int argc, char** argv)
{
QApplication app(argc, argv);
auto win = new MyWindow;
win->show();
return app.exec();
}
I have a problem that, after closing a QDialog with web content, the QWebEngineProcess.exe process is not closing.
Here is a minimal example:
#include <QApplication>
#include <QWebEngineView>
#include <QWebEngineSettings>
#include <QDialog>
#include <QMainWindow>
#include <QLayout>
#include <QtGui>
#include <QPushButton>
class Dialog : public QDialog
{
public:
Dialog() : QDialog(nullptr)
{
resize(512, 512);
setAttribute(Qt::WA_DeleteOnClose);
auto verticalLayout = new QVBoxLayout(this);
verticalLayout->setSpacing(0);
verticalLayout->setContentsMargins(0, 0, 0, 0);
m_webView = new QWebEngineView(this);
verticalLayout->addWidget(m_webView);
}
void openPage(const QUrl& url)
{
m_webView->setUrl(url);
}
private:
QWebEngineView* m_webView;
};
class MainWindow : public QMainWindow
{
public:
MainWindow() : QMainWindow(nullptr)
{
resize(512, 512);
QPushButton* btn = new QPushButton("open web dialog", this);
connect(btn, &QPushButton::clicked, [this] ()
{
if (m_dialog == nullptr)
{
m_dialog = new Dialog();
m_dialog->openPage(QUrl("https://www.qt.io"));
m_dialog->show();
}
});
}
private:
QPointer<Dialog> m_dialog;
};
int main(int argc, char *argv[])
{
QCoreApplication::setOrganizationName("QtExamples");
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
I'm expecting that, after the dialog is closed, QWebEngineProcess.exe will be closed too, because I'm not using webengine anymore.
P.S. During opening WebPage, I have 2 QWebEngineProcess.exe. One is disappearing, but the second one left.
For any QObject instances (such as QDialog and QWebEngineView), the destructor of a parent object destroys all child objects. This means, for every object you new, it must either have a parent, or you must delete it manually, otherwise you are creating a leak and objects will remain open (not deleted).
You are creating a QWebEngineView object with the correct parent, but the parent (the Dialog) doesn't have a parent (you initialize the parent to nullptr). This means the Dialog would delete the QWebEngineView, except it never is deleted itself.
To fix it, either delete the Dialog (stored in m_dialog) manually in the MainWindow destructor (not recommended), or initialize it correctly with the MainWindow as its parent.
This may also be related to a bug in Qt 5.11 and 5.12. If this is the problem, the recommended solution is to add QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); at the top of your main() function (before declaring the QApplication).
I have a simple Qt MainWindow:
// ui/mainwindow.hpp
class MainWindow: public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = 0);
public slots:
private:
};
// ui/mainwindow.cpp
MainWindow::MainWindow(QWidget* parent): QMainWindow(parent)
{
QMenu* menuFile = menuBar()->addMenu(tr("File"));
menuFile->addAction(tr("Some"));
}
// Application entry
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
I'm noticing that with Ubuntu and Unity, the menu bar is not showing on the top of the screen but instead inside the application's window.
How do I make the menu bar show up on the top of the screen?
Which version of Qt are you using?
For Qt 4.8, the package appmenu-qt needs to be installed.
For Qt 5.2+, the package appmenu-qt5 needs to be installed and QT_QPA_PLATFORMTHEME=appmenu-qt5` being set in the environment
This is not really something that you influence on the app developer's side.
I've written this piece of code following some guys tutorial but I can't get it to run. The error says:
setMainQmlFile`, rootObject and showExpanded are not members of
QQmlApplicationEngine
What it's supposed to do is get a signal from QML and print out a message (in console). Basically I'm trying to integrate C++ and QML.
EDIT
I've tried to replace some of the functions with some others that seemed appropriate (at least to me). I've also tried to find what to include so that these functions would work but with no luck.
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "qtquickglobal.h"
#include <QQmlContext>
#include "myclass.h"
#include <QtCore>
#include <QtDebug>
#include <QQuickWindow>
int main(int argc, char *argv[]){
//Q_OBJECT;
QGuiApplication app(argc, argv);
QQmlApplicationEngine viewer;
viewer.load(QUrl(QStringLiteral("Qt/Versuch2/main.qml")));
myclass data;
viewer.rootContext() ->setContextProperty("myclassData", &data);
viewer.setMainQmlFile(QStringLiteral("qml/Versuch2/main.qml"));
QObject *viewerobject = viewer.rootObject();
QObject::connect(viewerobject, SIGNAL(qmlSignal(QString)), &data, SLOT(cppSlot(QString)));
viewer.showExpanded();
return app.exec();
}
void myclass::cppSlot(QString msg) {
qDebug() <<QString ("Called the cpp slot with message: %1").arg(msg);
}
Thank You.
I don't know where did you find you tutorial but, regarding Qt documentation, there is no such methods as setMainQmlFile nor showExpanded for QQmlApplicationEngine.
For setMainQmlFile(...), try to use instead setSource(...).
For showExpanded(), it's a QWidget function, and QQmlApplicationEngine do not inherit QWidget.
Regarding rootObject(), it might be a typo, you can use rootObjects() which return a QList<QObject*>.
Edit: Looks like you'll have to use the Qt Quick 2 Application wizard of Qt Creator in order to re-create that QtQuick2ApplicationViewer class used in the tutorial you found.
Using Qt 5.4.0 and Qt Creator 3.3.0, create New Project:
Click New Project
Qt Quick Application
Click Choose...
Name the project and select where to place it
Click Next
Select Qt Quick 2.4 from the drop-down menu
Click Next
Select desired Kit(s)
Click Next
Click Finish
Now You should see open main.qml file with following code:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
Qt.quit();
}
}
}
Make changes to the file so that it looks like the following:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
//### New Code ###
signal myQmlSignal(string msg)
//################
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
//### New Code ###
//Replace "Qt.quit();" with
console.log("Sending myQmlSignal from QML...");
myQmlSignal("Hello from QML")
//################
}
}
}
Add new class to Your project:
Right Mouse Click project name in Projects viewer
Click Add New...
Select C++ Class if not already selected
Click Choose...
In Class name filed enter "MyCppClass"
Set Base class to QObject
Click Next
Click Finish
Open mycppclass.h file, it should look like the following:
#ifndef MYCPPCLASS_H
#define MYCPPCLASS_H
#include <QObject>
class MyCppClass : public QObject
{
Q_OBJECT
public:
explicit MyCppClass(QObject *parent = 0);
~MyCppClass();
signals:
public slots:
};
#endif // MYCPPCLASS_H
Make changes to mycppclass.h so it looks like this:
#ifndef MYCPPCLASS_H
#define MYCPPCLASS_H
#include <QObject>
//### New Code ###
#include <QDebug>
//################
class MyCppClass : public QObject
{
Q_OBJECT
public:
explicit MyCppClass(QObject *parent = 0);
~MyCppClass();
signals:
public slots:
//### New Code ###
void myCppSlot(const QString &msg);
//################
};
#endif // MYCPPCLASS_H
Open mycppclass.cpp, which should look like this:
#include "mycppclass.h"
MyCppClass::MyCppClass(QObject *parent) : QObject(parent)
{
}
MyCppClass::~MyCppClass()
{
}
Change it to this:
#include "mycppclass.h"
MyCppClass::MyCppClass(QObject *parent) : QObject(parent)
{
}
MyCppClass::~MyCppClass()
{
}
void MyCppClass::myCppSlot(const QString &msg)
{
//### New Code ###
qDebug() << "Signal was received by C++. It contains follwoing message: " << msg;
//################
}
Open main.cpp, which looks like this:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
And make following changes:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
//### New Code ###
#include "mycppclass.h"
//################
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
//### New Code ###
MyCppClass myCppClass;
QObject::connect(engine.rootObjects().takeFirst(), SIGNAL(myQmlSignal(QString)), &myCppClass, SLOT(myCppSlot(QString)));
//################
return app.exec();
}
Click big green triangle to compile and run Your application. Watch Application Output area, click Hello World, You should see following message being printed out:
qml: Sending myQmlSignal from QML...
Signal was received by C++. It contains follwoing message: "Hello from QML"
Hello all
I have main windows application and I like to popup dialog for settings when the application (the qMainWindow)
Is fully loaded ? I tried to just in the main window constructor:
SettingsDialog settingsDialog;
settingsDialog.exec();
but when I start my application I see the QDialog and the main window minimized in the background
what I need that my main windows will be in the background but not minimized and the QDialog in the middle blocking the main
windows until ok button is preset
Use QTimer::singleShot with zero time interval it will call specified slot from the event loop when constructor and show() have been completed. Here is an example:
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QDialog>
#include <QtGui/QMainWindow>
class MW : public QMainWindow
{
Q_OBJECT
public:
MW();
private slots:
void showDialog();
};
MW::MW()
{
QTimer::singleShot(0, this, SLOT(showDialog()));
}
void MW::showDialog()
{
QDialog d;
d.setWindowTitle("dialog");
d.exec();
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MW mw;
mw.show();
app.exec();
}