I have a QT application and I'm trying to have a button in one of my windows open another window.
The way I have done my window objects so far in the main is like this:
Website control;
control.show();
This displays my first window fine and if I declare my other window in a similar way that also displays at runtime, although this is not what I want
Then in a separate header file:
class Website: public QWidget, public Ui::Website
{
public:
Website();
}
Then in the corresponding Cpp file I have:
Website::Website()
{
setupUi(this);
}
Now all this works and have added a custom slot so that when I click a button it triggers a slot in my other cpp file. The issue is I'm not sure how to show my other window as I declare them in my main so can't access them to do .show()?
Any help would be appreciated, I'm fairly new to C++ and QT
It's not clear to me what you want to do. But i might understand your struggle as I had one myself the first time approaching this framework.
So let's say you have a MainWindow class that controls the main Window view. Than you want to create a second window controlled by Website class.
You then want to connect the two classes so that when you click a button on the Website window something happens in the MainWindow.
I made a simple example for you that is also on GitHub:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "website.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void changeText();
private slots:
void on_openButton_clicked();
private:
Ui::MainWindow *ui;
//You want to keep a pointer to a new Website window
Website* webWindow;
};
#endif // MAINWINDOW_H
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::changeText()
{
ui->text->setText("New Text");
delete webWindow;
}
void MainWindow::on_openButton_clicked()
{
webWindow = new Website();
QObject::connect(webWindow, SIGNAL(buttonPressed()), this, SLOT(changeText()));
webWindow->show();
}
website.h
#ifndef WEBSITE_H
#define WEBSITE_H
#include <QDialog>
namespace Ui {
class Website;
}
class Website : public QDialog
{
Q_OBJECT
public:
explicit Website(QWidget *parent = 0);
~Website();
signals:
void buttonPressed();
private slots:
void on_changeButton_clicked();
private:
Ui::Website *ui;
};
#endif // WEBSITE_H
website.cpp
#include "website.h"
#include "ui_website.h"
Website::Website(QWidget *parent) :
QDialog(parent),
ui(new Ui::Website)
{
ui->setupUi(this);
}
Website::~Website()
{
delete ui;
}
void Website::on_changeButton_clicked()
{
emit buttonPressed();
}
Project composed:
SOURCES += main.cpp\
mainwindow.cpp \
website.cpp
HEADERS += mainwindow.h \
website.h
FORMS += mainwindow.ui \
website.ui
Consider the Uis to be composed:
Main Window: a label called "text" and a button called "openButton"
Website Window: a button called "changeButton"
So the keypoints are the connections between signals and slots and the management of windows pointers or references.
Related
I'm new to QtCreator and created a button on the mainwindow that opens a dialog. In the dialog i added QLineEdit and a button. When i click on this button, i want the input text to be displayed on a Qlabel in the mainwindow.
I found another question which is basicly the same, but for me it has to work the other way around.
So In the header of MainWindow.h i have added to public:
void setLabelText(QString str);
I created the getter/setter function and added it to MainWindow.cpp:
void MainWindow::setLabelText(QString str)
{
ui->label->setText(str);//it is label dialog
}
And in the windowdialog.cpp i have added under button click() slot:
void WindowDialog::on_pushButton_clicked()
{
QString str = ui->lineEdit->text();
MainWindow MainWindow;
MainWindow.setLabelText(str);
}
It compiles without errors. Yet when i click on the button in the dialog, it won't print the results in the mainwindow... I have been trying to find another examples about how to do this, but couldn't really find one yet. So what am i missing? Or how do i make this work?
You can use signals and slots for this. https://doc.qt.io/qt-5/signalsandslots.html
you would need to connect the signal to a slot by using this command
connect(dlg,&DialogWindow::transmit,this,&MainWindow::update);
anytime you want to call the update function you would just need to emit the signal.
emit transmit(ui->lineEdit->text());
I created a dialog window class in this example.
Dialog.h
#ifndef DIALOGWINDOW_H
#define DIALOGWINDOW_H
#include <QDialog>
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class DialogWindow : public QDialog
{
Q_OBJECT
public:
DialogWindow(QWidget *parent = nullptr);
~DialogWindow();
signals:
void transmit(QString txt);
private slots:
void on_buttonBox_accepted();
private:
Ui::Dialog *ui;
};
#endif // DIALOGWINDOW_H
Dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
DialogWindow::DialogWindow(QWidget *parent)
: QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
DialogWindow::~DialogWindow()
{
}
void DialogWindow::on_buttonBox_accepted()
{
emit transmit(ui->lineEdit->text());
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dialog.h"
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();
void update(QString txt);
private:
Ui::MainWindow *ui;
DialogWindow *dlg;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
dlg = new DialogWindow(NULL);
connect(dlg,&DialogWindow::transmit,this,&MainWindow::update);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
dlg->show();
}
void MainWindow::update(QString txt)
{
ui->label->setText(txt);
}
In this line MainWindow MainWindow;, you create a new MainWindow, but you want to set the text on your existing MainWindow.
Instead you might want to pass a reference or pointer to the MainWindow to the dialog, once you create it.
If you pass your MainWindow as the parent of the QDialog, you could do it this way:
void WindowDialog::on_pushButton_clicked()
{
QString str = ui->lineEdit->text();
static_cast<MainWindow*>(parent())->setLabelText(str);
}
A safer version using dynamic_cast:
void WindowDialog::on_pushButton_clicked()
{
QString str = ui->lineEdit->text();
MainWindow* window = dynamic_cast<MainWindow*>(parent());
if (!window) {
throw std::runtime_error{"Parent was not a MainWindow"};
}
window->setLabelText(str);
}
I am new to Qt and am have to make a GUI having multiple windows for this I found QStackedWidget class using Qt designer tools.
I added QStackedWidget using add new->Qt designer form class->Qstackwidget
after that I created an object of this class in my main window
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<stackedwidget.h>
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;
StackedWidget *stk; };
#endif // MAINWINDOW_H
then i tried to display StackedWidget by:
#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_pushButton_clicked()
{
stk = new StackedWidget(this);
stk->show();
}
But stackwidget is not opening .
Can someone tell me what am I doing wrong and how to implement QStackedWidget GUI using designer tools?
The QStackedWidget class provides a stack of widgets where only one widget is visible at a time.
You are new to Qt so I suggest you to using Qt Designer:
You can drag&drop StackedWidget to your form, customize it then use arrows to go to the next page and work on it too.
StackedWidget is like a vector you can access them via indexes.
ui->stackedWidget->setCurrentIndex(1);
I would like to have the tool icons at the right side, rather than at the top. As I experienced, I can move them manually, I can set their orientation() to vertical, but they remain at the top; I can set setAllowedAreas() which means I restrict where the toolbar areas can reside, but the tool buttons reside at the top. I need something like setToolbarArea(). Is there something similar?
You can call addToolBar again to move the toolbar.
According to the documentation,
If the main window already manages toolbar then it will only move the
toolbar to area.
I.e.
mainwindow.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:
Ui::MainWindow *ui;
QToolBar * toolBar;
public slots:
void moveLeft();
void moveRight();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
toolBar= new QToolBar("Tool Bar");
toolBar->addAction(QIcon(":/qt.png"), "FirstAction", this, SLOT(moveLeft()));
toolBar->addAction(QIcon(":/qt.png"), "SecondAction", this, SLOT(moveRight()));
addToolBar(Qt::RightToolBarArea, toolBar);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::moveLeft()
{
addToolBar(Qt::LeftToolBarArea, toolBar);
}
void MainWindow::moveRight()
{
addToolBar(Qt::RightToolBarArea, toolBar);
}
I've set up a basic Qt-Widgets-Application (Qt 5.5 community) with a simple QWidget "MainWindow" and an additinal QWidget "SettingsScreen".
Within the "MainWindow", touchscreen-events (handled by OS) are working as expected, but after opening the "SettingsScreen" all touch-events are executed on the desktop until I close the "SettingsScreen" using mouse or keyboard.
Environment:
Ubuntu Studio 14.04.03
Qt 5.5 Open Source Edition
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <settingsscreen.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_btnExit_clicked();
void on_btnSettings_clicked();
private:
Ui::MainWindow *ui;
SettingsScreen *wSettingsScreen;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsscreen.h"
#include "ui_settingsscreen.h"
MainWindow::MainWindow(QWidget *parent) : QWidget(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnExit_clicked()
{
this->close();
}
void MainWindow::on_btnSettings_clicked()
{
wSettingsScreen = new SettingsScreen(parentWidget());
wSettingsScreen->show();
}
settingsscreen.h
#ifndef SETTINGSSCREEN_H
#define SETTINGSSCREEN_H
#include <QWidget>
namespace Ui {
class SettingsScreen;
}
class SettingsScreen : public QWidget
{
Q_OBJECT
public:
explicit SettingsScreen(QWidget *parent = 0);
~SettingsScreen();
private slots:
void on_pushButton_clicked();
void on_btnBack_clicked();
private:
Ui::SettingsScreen *ui;
};
#endif // SETTINGSSCREEN_H
settingsscreen.cpp
#include "settingsscreen.h"
#include "ui_settingsscreen.h"
SettingsScreen::SettingsScreen(QWidget *parent) :
QWidget(parent),
ui(new Ui::SettingsScreen)
{
ui->setupUi(this);
}
SettingsScreen::~SettingsScreen()
{
delete ui;
}
void SettingsScreen::on_btnBack_clicked()
{
this->close();
}
I've just started developing with Qt, so please forgive me if I'm missing something essential :)
Any help would by highly appreciated!!
Thank you in advance!
Actually the thing is QMainwindow or any base Widget of your application is able to properly synthesize the Unhandled touch screen events to Mouse events. So whenever you are creating a dialog/widget, make sure to set Mainwindow as there parent and in the constructor of the child widget use setParent(parent). Even I was facing this kind of Issue and this worked for me.
bottom line is i have 2 forms , first mainwindow 2nd form1 . i have a button on mainwindow that displays form 2 . now i have a button on form1 that should take me to mainwindow but it is not working. problem is when i say #include in form1.h it gives me an error i.e mainwindow does not have a name type. please help , working example would be great if possible . Actual error is MainWindow does not have a name type
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <form1.h>
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; // i put this line of code in public section when i was trying ui->show(); in form1.cpp file
Form1 obj ; // to show next form
};
#endif // MAINWINDOW_H
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_pushButton_clicked()
{
obj.show();
this->hide();
}
Form1.h
#ifndef FORM1_H
#define FORM1_H
#include <QWidget>
#include<mainwindow.h>
namespace Ui {
class Form1;
}
class Form1 : public QWidget
{
Q_OBJECT
public:
explicit Form1(QWidget *parent = 0);
~Form1();
private slots:
void on_pushButton_clicked();
private:
Ui::Form1 *ui;
MainWindow mw ; // here i am making object of main window
};
#endif // FORM1_H
form1.cpp
#include "form1.h"
#include "ui_form1.h"
#include<mainwindow.h> // i know when i include this there this issue occurs , but i want to go my previous form to show and for that i have to make its object ! thats how it works when i am going to my next form i.e form1 now i want to go back
Form1::Form1(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form1)
{
ui->setupUi(this);
}
Form1::~Form1()
{
delete ui;
}
void Form1::on_pushButton_clicked() // show mainWindow
{
mw->show();
this->hide();
//MainWindow::ui->show(); // i even tried this
}
i also tried if i could do it without including mainwindow.h in form1.h by puttin Ui::MainWindow *ui; in public section so form1.cpp file i could access it by typing MainWindow::ui->show(); this time ERROR says Object is missing Reference to 'MainWindow::ui'
You have a circular dependency between the classes MainWindow and Form1. Thus, you include form1.h in mainwindow.h and mainwindow.h in form1.h. When the compiler reaches the line
MainWindow mw ; // here i am making object of main window
it is the first time he encounters the symbol MainWindow and trigger that error.
I still don't understand why mw is a member of Form1, but you can break the dependency using a pointer instead. Basically you will now have
MainWindow* mw ;
And rather than #include<mainwindow.h> in Form1.h you will just have to forward declare
class MainWindow;