change theme with radio button Qwidget in Qt C++ - c++

I want to change my application Theme with QRadioButton in the QWidget application.
can anyone help me?
I have a Setting class that has some settings and one of them is changing the theme between dark and light.
it is a C++ app with OpenGL.
void Settings::on_DarkTheme_clicked()
{
}
void Settings::on_lightTheme_clicked()
{
}
what should I have to write in these 2 methods?
I used .qss file like this
int main(int argc, char *argv[])
{
QSurfaceFormat fmt;
fmt.setVersion(3,3);
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setSamples(8);
fmt.setOption(QSurfaceFormat::StereoBuffers);
fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
QSurfaceFormat::setDefaultFormat(fmt);
loadSettings();
App app(argc, argv);
QFile stylesheetFile("./Combinear.qss");
stylesheetFile.open(QFile::ReadOnly);
QString stylesheet = QLatin1String(stylesheetFile.readAll());
app.setStyleSheet(stylesheet);
MainWindow w;
w.show();
const auto returnValue = app.exec();
App::setFinished();
return returnValue;
}
but it didn't Work and I'm confused

First of all, I add a radioButton in my mainwindow.ui .
this is my 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();
signals:
void changedDark();
void changedLight();
private slots:
void on_radioButton_clicked(bool checked);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
and my mainwindow.cpp :
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_radioButton_clicked(bool checked)
{
if (checked)
{
ui->radioButton->setText("Dark");
emit changedDark();
}
else
{
ui->radioButton->setText("Light");
emit changedLight();
}
}
and my main.cpp:
#include "mainwindow.h"
#include <QApplication>
#include <QFile>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
QObject::connect(&w, &MainWindow::changedDark, &a, [&]
{
/**
* Load the application style
*/
QFile dark_styleFile(":/theme/themes/MaterialDark.qss");
dark_styleFile.open(QFile::ReadOnly);
/**
* Apply the loaded stylesheet
*/
QString style(dark_styleFile.readAll());
a.setStyleSheet(style);
});
QObject::connect(&w, &MainWindow::changedLight, &a, [&]
{
/**
* Load the application style
*/
QFile light_styleFile(":/theme/themes/Ubuntu.qss");
light_styleFile.open(QFile::ReadOnly);
/**
* Apply the loaded stylesheet
*/
QString style(light_styleFile.readAll());
a.setStyleSheet(style);
});
return a.exec();
}
This is my result:
you can clone it from this repo:
https://github.com/parisa-hr/qt-theme-example

Related

Qt widget takes a long time until it starts to receive mouse events in full screen mode on macOS

In normal screen mode, Qt widgets receive mouse events immediately after creation. In full-screen mode on macOS, however, it takes a while until the widget starts receiving those events. From my tests, it takes ~700ms on average until a widget receives its first mouse event versus ~30ms in normal screen mode. Why does it take so long for mouse events to stream in when using full-screen mode? Is there a way to force Qt to receive those events earlier? See my test in the GIF animation below.
The source code for my test follows below.
/**
* main.cpp
*/
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return QApplication::exec();
}
/**
* mainwindow.h
*/
#pragma once
#include "popupwindow.h"
#include <QWidget>
#include <QPushButton>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private slots:
void handleFullScreenButton();
void handleNormalScreenButton();
private:
PopupWindow* m_fullScreenWindow;
QPushButton* m_fullScreenButton;
QPushButton* m_normalScreenButton;
PopupWindow* m_normalScreenWindow;
};
/**
* popupwindow.h
*/
#pragma once
#include <QWidget>
#include <QLabel>
class PopupWindow : public QWidget
{
Q_OBJECT
public:
explicit PopupWindow(QWidget* parent = nullptr);
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
private:
void showText(const QString &text);
QLabel* m_text;
qint64 m_creationTimestamp;
bool m_eventReceived;
};
/**
* mainwindow.cpp
*/
#include "mainwindow.h"
#include <QDebug>
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
: m_normalScreenWindow(nullptr)
, m_fullScreenWindow(nullptr)
{
auto *layout = new QVBoxLayout(this);
m_normalScreenButton = new QPushButton("Popup screen");
m_fullScreenButton = new QPushButton("Popup full screen");
connect(m_normalScreenButton, &QPushButton::released, this, &MainWindow::handleNormalScreenButton);
connect(m_fullScreenButton, &QPushButton::released, this, &MainWindow::handleFullScreenButton);
layout->addWidget(m_normalScreenButton);
layout->addWidget(m_fullScreenButton);
}
void MainWindow::handleNormalScreenButton() {
m_normalScreenWindow = new PopupWindow(this);
m_normalScreenWindow->show();
m_normalScreenWindow->activateWindow();
m_normalScreenWindow->raise();
}
void MainWindow::handleFullScreenButton() {
m_fullScreenWindow = new PopupWindow(this);
m_fullScreenWindow->showFullScreen();
m_fullScreenWindow->activateWindow();
m_fullScreenWindow->raise();
}
/**
* popupwindow.cpp
*/
#include "popupwindow.h"
#include <QDateTime>
#include <QDebug>
#include <QHBoxLayout>
PopupWindow::PopupWindow(QWidget *parent)
: m_creationTimestamp(QDateTime::currentMSecsSinceEpoch())
, m_eventReceived(false)
, m_text(nullptr)
{
setAttribute(Qt::WA_DeleteOnClose);
setMouseTracking(true);
}
void PopupWindow::mouseMoveEvent(QMouseEvent *event) {
if (m_eventReceived) {
return;
}
auto deltaTimeMs = QDateTime::currentMSecsSinceEpoch() - m_creationTimestamp;
showText(QString("First mouse event received after %1 ms.").arg(deltaTimeMs));
m_eventReceived = true;
}
void PopupWindow::mousePressEvent(QMouseEvent *event) {
showNormal();
close();
}
void PopupWindow::showText(const QString &text) {
m_text = new QLabel(text);
m_text->setStyleSheet("font: 26pt;");
auto *layout = new QVBoxLayout(this);
layout->addWidget(m_text, Qt::AlignCenter);
}

Qt calling close() closes the MainWindow instead of the dialog window

In my sample application, the MainWindow closes instead of the dialog window. Why is that and how do I change it?
I've tried setQuitOnLastWindowClosed() but it didn't have any effect.
When clicking the x in the top right corner, the dialog window closes and the MainWindow remains open as expected. But that's of course not what I want.
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDialog>
#include <QWidget>
#include <QPushButton>
#include <QHBoxLayout>
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
void on_mainWindowBtn();
void on_closeBtn();
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *mainWindowWidget = new QWidget(this);
QHBoxLayout *mainWindowHBox = new QHBoxLayout();
QPushButton *mainWindowPushButton = new QPushButton();
mainWindowPushButton->setText("Open Dialog Window");
mainWindowHBox->addWidget(mainWindowPushButton);
mainWindowWidget->setLayout(mainWindowHBox);
this->setCentralWidget(mainWindowWidget);
connect(mainWindowPushButton, &QPushButton::released, this, &MainWindow::on_mainWindowBtn);
}
void MainWindow::on_mainWindowBtn()
{
QDialog *newDialog = new QDialog();
QHBoxLayout *newHBox = new QHBoxLayout();
QPushButton *closeBtn = new QPushButton();
closeBtn->setText("Close Dialog Window");
newHBox->addWidget(closeBtn);
newDialog->setLayout(newHBox);
newDialog->setModal(true);
connect(closeBtn, &QPushButton::released, this, &MainWindow::on_closeBtn);
newDialog->exec();
}
void MainWindow::on_closeBtn()
{
close(); // closes the MainWindow but not the dialog window
}
MainWindow::~MainWindow()
{
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(false);
MainWindow w;
w.show();
return a.exec();
}

QComboBox currentIndex() to hide other widgets

What it should do: When the QComboBox is on the first item (index 0) it should hide the QStackedWidget. Which causes the QComboBox to extend as much as possible. As soon as you change the item in the QComboBox to anything, the QComboxBox should shrink and the QStackedWidget should display the correct page.
What I have and what it does instead: I test what the current index item is of the QComboBox and depending on that I change the size policies and visibility of widgets in order to obtain what I want. But it doesn't work. I tried to do workarounds but I cant seem to figure this out.
I also used qDebug() to see what currentIndexItem returns, and it seems to be stuck at 0, no matter to what index I change the QComboBox to. Do I have to update the currentItemIndex?
Note: I have a signal connected in the designer from QComboBox to QStackedWidget: currentIndexChanged(int) -> setCurrentIndex(int)
Here is my code.
My code:
interfacewindow.h
#ifndef INTERFACEWINDOW_H
#define INTERFACEWINDOW_H
#include <QMainWindow>
#include <QPainter>
#include <QComboBox>
namespace Ui
{
class InterfaceWindow;
}
class InterfaceWindow : public QMainWindow
{
Q_OBJECT
public:
explicit InterfaceWindow(QWidget *parent = 0);
~InterfaceWindow();
private:
Ui::InterfaceWindow *ui;
private slots:
void on_actionClose_triggered();
};
#endif // INTERFACEWINDOW_H
interfacewindow.cpp
#include "interfacewindow.h"
#include "ui_interfacewindow.h"
#include <QDebug>
InterfaceWindow::InterfaceWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::InterfaceWindow)
{
ui->setupUi(this);
if(ui->comboBox->currentIndex() == 0)
{
ui->comboBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
ui->stackedWidget->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
ui->stackedWidget->setVisible(false);
}
else
{
ui->comboBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
ui->stackedWidget->setVisible(true);
}
}
InterfaceWindow::~InterfaceWindow()
{
delete ui;
}
void InterfaceWindow::on_actionClose_triggered()
{
this->close();
}
main.cpp
#include <QApplication>
#include "interfacewindow.h"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
InterfaceWindow w;
w.show();
return a.exec();
}

Qt signal-slot not working

I want to update text in a label in a first window from a second window where is a line edit to write some text. This text should be dispaly in first window.
I spend a week for it.
A famous connect doesn't work.
Is somebody who correct below code and explain how connect should work?
I use Qt in version 5.1.1
firstwindow.h
#ifndef FIRSTWINDOW_H
#define FIRSTWINDOW_H
#include <QMainWindow>
#include "secondwindow.h"
namespace Ui {
class Firstwindow;
}
class Firstwindow : public QMainWindow
{
Q_OBJECT
public:
explicit Firstwindow(QWidget *parent = 0);
~Firstwindow();
public slots:
void addEntry();
private slots:
void on_pushButton_clicked();
private:
Ui::Firstwindow *ui;
Secondwindow *asecondwindow;
Secondwindow *absecondwindow;
Secondwindow *abcsecondwindow;
};
#endif // FIRSTWINDOW_H
secondwindow.h
#ifndef SECONDWINDOW_H
#define SECONDWINDOW_H
#include <QDialog>
#include <QtWidgets>
namespace Ui {
class Secondwindow;
}
class Secondwindow : public QDialog
{
Q_OBJECT
public:
explicit Secondwindow(QWidget *parent = 0);
~Secondwindow();
QLineEdit *lineEdit;
private slots:
void on_pushButton_clicked();
private:
Ui::Secondwindow *ui;
QPushButton *pushButton;
};
#endif // SECONDWINDOW_H
main.cpp
#include "firstwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Firstwindow w;
w.show();
return a.exec();
}
firstwindow.cpp
#include "firstwindow.h"
#include "ui_firstwindow.h"
#include <QtCore>
#include <QtGui>
#include <QtWidgets>
Firstwindow::Firstwindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Firstwindow)
{
ui->setupUi(this);
asecondwindow = new Secondwindow();
QObject::connect(asecondwindow->lineEdit,SIGNAL(textChanged()),this, SLOT(addEntry()));
}
Firstwindow::~Firstwindow()
{
delete ui;
delete asecondwindow;
delete absecondwindow;
delete abcsecondwindow;
}
void Firstwindow::on_pushButton_clicked()
{
absecondwindow = new Secondwindow;
absecondwindow->exec();
}
void Firstwindow::addEntry()
{
abcsecondwindow = new Secondwindow;
if (abcsecondwindow->exec()) {
QString name = abcsecondwindow->lineEdit->text();
ui->label->setText(name);
}
}
secondwindow.cpp
#include "secondwindow.h"
#include "ui_secondwindow.h"
#include <QDialog>
Secondwindow::Secondwindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::Secondwindow)
{
ui->setupUi(this);
}
Secondwindow::~Secondwindow()
{
delete ui;
}
void Secondwindow::on_pushButton_clicked()
{
// emit ui->lineEdit->textChanged();
QDialog::accept();
}
I see the following issues:
QLineEdit does not have a signal textChanged(). It should be textChanged(const QString &) instead. So you have to install your connection like:
QObject::connect(asecondwindow->lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(addEntry(const QString &)));
Please note that I changed the Firstwindow::addEntry() slot to Firstwindow::addEntry(const QString &) to match the signal's signature.
I cannot find when and where your QLineEdit member variable of the Secondwindow class is created.
There is a fundamental design problem with what you're doing. There's no need to expose the second window's internal properties to the first window. Just listen for changes within the second window and emit a signal whenever it changes. Then the first window can just listen to the changes on the second window.
Here's a full example showing what I mean. main.cpp:
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QMainWindow>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
class SecondWindow : public QDialog {
Q_OBJECT
public:
SecondWindow(QMainWindow *parent = 0) : QDialog(parent) {
QLineEdit *edit = new QLineEdit;
QPushButton *close = new QPushButton(QStringLiteral("close"));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(edit);
layout->addWidget(close);
setLayout(layout);
connect(edit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
connect(close, SIGNAL(clicked()), this, SLOT(close()));
}
signals:
void textChanged(const QString &text);
};
class FirstWindow : public QMainWindow {
Q_OBJECT
public:
FirstWindow(QMainWindow *parent = 0) : QMainWindow(parent) {
QWidget *central = new QWidget(this);
QPushButton *button = new QPushButton(QStringLiteral("Open"));
label = new QLabel(QStringLiteral("Output appears here"));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button);
layout->addWidget(label);
central->setLayout(layout);
setCentralWidget(central);
connect(button, SIGNAL(clicked()), this, SLOT(createWindow()));
}
private slots:
void createWindow() {
SecondWindow *window = new SecondWindow(this);
connect(window, SIGNAL(textChanged(QString)), this, SLOT(setLabelText(QString)));
window->resize(300, 300);
window->exec();
}
void setLabelText(const QString &text) {
label->setText(text);
}
private:
QLabel *label;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FirstWindow w;
w.resize(400, 400);
w.show();
return a.exec();
}
#include "main.moc"
Not that the SecondWindow listens for changes on the QLineEdit and emits its own signal when that value changes. Then the FirstWindow just connects to that signal and changes its own QLabel whenever it receives the signal.

QtPushButton wont click

Hello Im working through Qt tutorials I've have copy the code for the communicate section of this tutorial. the code compiles and shows but none of my buttons are clickable.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class QPushButton;
class QLabel;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void OnPlus();
void OnMinus();
private:
Ui::MainWindow *ui;
QLabel *label;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtGui>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QPushButton *plus = new QPushButton("+", this);
plus->setGeometry(50, 40, 75, 30);
QPushButton *minus = new QPushButton("-", this);
minus->setGeometry(50, 100, 75, 30);
label = new QLabel("0", this);
label->setGeometry(190, 80, 20, 30);
connect(plus, SIGNAL(clicked()), this, SLOT(OnPlus()));
connect(minus, SIGNAL(clicked()), this, SLOT(OnMinus()));
ui->setupUi(this);
}
void MainWindow::OnPlus()
{
int val = label->text().toInt();
val++;
label->setText(QString::number(val));
}
void MainWindow::OnMinus()
{
int val = label->text().toInt();
val--;
label->setText(QString::number(val));
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QPushButton>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
Your problem is with this line:
ui->setupUi(this);
It creates an invisible central widget for your main window, which blocks all events destined for your buttons, which is why they don't depress when you click them. Move this line to the beginning of your constructor for MainWindow and the problem will go away.