Qt::FramelessWindowHint setSizeConstraint sideffects on closeevent - c++

When using Qt::FramelessWindowHint with setSizeConstraint my widget does not recieve close events anymore, is this a bug? Minimal test example:
pro
QT += core gui
TARGET = QT-BUG
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget(){}
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QCloseEvent>
Widget::Widget(QWidget *parent) : QWidget(parent)
{
setWindowFlags(Qt::Tool
| Qt::FramelessWindowHint
| Qt::WindowStaysOnTopHint);
QVBoxLayout *l2 = new QVBoxLayout(this);
l2->setSizeConstraint(QLayout::SetFixedSize);
this->setLayout(l2);
QLineEdit* _inputLine = new QLineEdit(this);
l2->addWidget(_inputLine);
}
main .cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

Window events like Close and Minimize are actually tied to the existence of buttons. Bit of a poor design choice by the Qt folks.
It seems that Qt::FramelessWindowHint removes/disables the buttons, but you can re-enable them (without displaying them) via other window hints. For close events, add Qt::WindowCloseButtonHint.

Related

Regarding Projector Programming using QT

I am connecting the projector to Quectel QCOM application. Now I want to skip that application and create my customized application to control the projector.
I wrote a program based on the guidelines of Quectel to switch off the projector. Following is the code. Even I used the QSerialPort code. But the projector couldn't switch off. However using the command prompt of the Quectel QCOM application, I could control the projector.
Please help me in this guys! I am stuck in this since a month.
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec(); //
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include<QSerialPort>
#include<string>
#include<QtGui>
#include <QMessageBox>
using namespace std;
QSerialPort *serial;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow() //
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QMessageBox::information(this,"Title here","Hello World");
serial = new QSerialPort(this);
serial->setPortName("COM3");
serial->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
serial->setDataBits(QSerialPort::Data8);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->setStopBits(QSerialPort::OneStop);
serial->setParity(QSerialPort::NoParity);
if(!serial->open(QIODevice::ReadWrite))
{
qDebug()<<"error: can't open com port";
}
QString command = "WT+LEDE=0\n";
QByteArray x = command.toLocal8Bit();
serial->write(x);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
QMake project file:
#-------------------------------------------------
Project created by QtCreator 2019-11-02T10:55:21
#-------------------------------------------------
QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = GUISerialPort
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui

QDialog with Qt::WindowMaximizeButtonHint incorrect after calling exec the second time

I have a QDialog with a maximize button and a small test runner.
main.cpp
#include <QApplication>
#include <QPushButton>
#include "MyDialog.h"
int main(int argc, char** args) {
QApplication app(argc, args);
auto widget=new MyDialog;
auto btn = new QPushButton("Show");
btn->show();
QObject::connect(btn, &QPushButton::clicked, [&]() {widget->exec(); });
app.exec();
}
MyDialog.h
#pragma once
#include <QDialog>
#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QFrame>
class MyDialog : public QDialog {
Q_OBJECT
public:
MyDialog(QWidget* parent = nullptr) : QDialog(parent) {
auto window = new QMainWindow;
auto frame = new QFrame;
frame->setLayout(new QHBoxLayout);
frame->layout()->addWidget(new QLabel("Test"));
window->setCentralWidget(frame);
setLayout(new QVBoxLayout);
layout()->setMargin(0);
layout()->addWidget(window);
setWindowFlags(windowFlags() | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
}
};
In my test runner I press [Show], then I maximize my dialog. Now I close the dialog by pressing the cross. Then I press [Show] again. After that I got the wrong rendering of my dialog.
How can I fix this behavior. The QLabel("Test")should occupy the whole screen.

Cannot play movie with QMediaPlayer

I try to play movie with Qt5 on OS X El Capitan v10.11.6.
I use QMediaPlayer, QMediaPlaylist, and QVideoWidget to play.
Write source code as same as Qt's documentation, but it show only black window and not play any movie.
Here is my source code.
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow mainwindow;
mainwindow.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
class QMediaPlayer;
class QMediaPlaylist;
class QVideoWidget;
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0);
private:
QMediaPlayer* player;
QMediaPlaylist* playlist;
QVideoWidget* videoWidget;
};
#endif
mainwindow.cpp
#include <QtWidgets>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QVideoWidget>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget* parent)
: QWidget(parent)
{
player = new QMediaPlayer;
playlist = new QMediaPlaylist;
videoWidget = new QVideoWidget;
player->setPlaylist(playlist);
player->setVideoOutput(videoWidget);
playlist->addMedia(QUrl::fromLocalFile("box.mp4"));
videoWidget->show();
playlist->setCurrentIndex(1);
player->play();
QHBoxLayout* mainLayout = new QHBoxLayout;
mainLayout->addWidget(videoWidget);
setLayout(mainLayout);
}
I check "box.mp4" exists in the same directory.
Where is problem? How should I fix source code to solve this problem?
Just modify media file path to full path in mainwindow.cpp.
Before
playlist->addMedia(QUrl::fromLocalFile("box.mp4"));
After
playlist->addMedia(QUrl::fromLocalFile("/path/to/box.mp4"));

in Qt Gui how to make a button randomly appear every click

Alright so is there any way to make this program randomly change the variables x and y every time the button is clicked i am new to programming...
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QtGUI>
#include <QWidget>
#include <cstdlib>
#include <ctime>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *window = new QWidget;
srand(time(0));
int x = 1+(rand()%900);
int y = 1+(rand()%400);
QPushButton *MainInter = new QPushButton("Push me!",window);
QPropertyAnimation *animation = new QPropertyAnimation(MainInter, "pos");
animation->setDuration(0);
animation->setEndValue(QPoint(x,y));
Object::connect(MainInter,SIGNAL(released()),animation,SLOT(start()));
window->resize(900,500);
window->show();
return a.exec();
}
What you can do is, instead of connecting the released() signal of your button directly to your animations start() SLOT, you would create your own custom SLOT. Then you connect the button to it, handle the action, and call the animation.
First read up on how to create a custom QWidget, instead of creating top level object in your main(). Simple example here
A custom widget might look like this:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class QPushButton;
class QPropertyAnimation;
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = 0);
private:
QPushButton *button;
QPropertyAnimation *animation;
public slots:
void randomizeAnim();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QPushButton>
#include <QPropertyAnimation>
#include <ctime>
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent)
{
button = new QPushButton("Push me!", this);
animation = new QPropertyAnimation(button, "pos");
animation->setDuration(0);
QObject::connect(button, SIGNAL(released()), this, SLOT(randomizeAnim()));
}
void MyWidget::randomizeAnim()
{
srand(time(0));
int x = 1+(rand()%900);
int y = 1+(rand()%400);
animation->setEndValue(QPoint(x,y));
animation->start();
}
And now your main.cpp can be reduced to the boilerplate code:
#include <QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *window = new MyWidget;
window->resize(900,500);
window->show();
return a.exec();
}
Every time you click, your custom slot will handle the action and do the animation.

Store settings of qt application using QSettings

Hello I have created an application using qt and I managed to save some of its settings using QSettings.
void DoneIt::writeSettings()
{
QSettings settings("mycompany", "RightDoneIt");
settings.beginGroup("DoneIt");
settings.setValue("size", size());
settings.setValue("pos", pos());
settings.endGroup();
}
void DoneIt::readSettings()
{
QSettings settings("mycompany", "RightDoneIt");
settings.beginGroup("DoneIT");
resize(settings.value("size", QSize(400, 400)).toSize());
move(settings.value("pos", QPoint(200, 200)).toPoint());
settings.endGroup();
}
That works fine with the window position and size.
I have add some widgets in my application using the designer of qt and I would like to save their state too.
One of my widgets is a radio button and I call it radioButtonbnw
How can I save its state (checked or unchecked) ?
What are the best practises ?
Put them to QButtonGroup.
Use QButtonGroup::setId to set Id for each radio button in this group.
Save the Id of the checked button get by QButtonGroup::checkedId.
Get the pointer of this button using QButtonGroup::button(id) when restore, and call QAbstractButton::setChecked.
BTW: if you want to saves the current state of mainwindow's toolbars and dockwidgets, use QMainWindow::saveState.
Here an example widget with three QRadioButton
settingspane.h
#ifndef SETTINGSPANE_H
#define SETTINGSPANE_H
#include <QWidget>
#include <QSettings>
class SettingsPane
: public QWidget
{
Q_OBJECT
QSettings *settings;
public:
explicit SettingsPane(QWidget *parent = nullptr);
public slots:
void handle_rb_buttonReleased(int id);
};
#endif // SETTINGSPANE_H
settingspane.cpp
#include "settingspane.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QRadioButton>
#include <QButtonGroup>
SettingsPane::SettingsPane(QWidget *parent)
: QWidget(parent)
{
settings = new QSettings();
auto mlayout = new QVBoxLayout();
setLayout(mlayout);
// create some buttons
auto rb_frst = new QRadioButton("first");
auto rb_scnd = new QRadioButton("second");
auto rb_thrd = new QRadioButton("third");
// container to organize groups of buttons (no visual)
auto buttonGroup = new QButtonGroup();
buttonGroup->addButton(rb_frst,0);
buttonGroup->addButton(rb_scnd,1);
buttonGroup->addButton(rb_thrd,2);
// layout buttons for visual representation
auto rb_layout = new QHBoxLayout();
rb_layout->addWidget(rb_frst);
rb_layout->addWidget(rb_scnd);
rb_layout->addWidget(rb_thrd);
mlayout->addLayout(rb_layout);
// use Functor-Based Connection due to overloaded buttonReleased
connect( buttonGroup,
SIGNAL(buttonReleased(int)),
this,
SLOT(handle_rb_buttonReleased(int)));
// restore button from settings
int id = settings->value("buttonGroup").toInt();
buttonGroup->button(id)->setChecked(true);
}
void
SettingsPane::handle_rb_buttonReleased(int id)
{
// save new status to the settings
settings->setValue("buttonGroup", id);
}
Using this in a MainWindow
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow
: public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "settingspane.h"
#include <QTabWidget>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
auto cwidget = new QTabWidget();
setCentralWidget(cwidget);
auto settingsPane = new SettingsPane();
cwidget->addTab(settingsPane,"Settings");
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
results in: