Passing a variable from MainWindow to new window - c++

In my MainWindow i have a combobox and a select button. When the select button is clicked a new window is opened.
I want to be able to create a QString variable on the MainWindow that contains the text from the combobox, and pass that QString to the new window. The new window is going to perform different tasks, based on the contents of the QString (based on the selection of the combobox).
The following is my code so far...
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "testwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->cmboTestSelect->addItem("{Please Select a Test}");
ui->cmboTestSelect->addItem("Test 1");
ui->cmboTestSelect->addItem("Test 2");
ui->cmboTestSelect->addItem("Test 3");
ui->cmboTestSelect->addItem("Test 4");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnTestSelect_clicked()
{
QString str_TestSelect = ui->cmboTestSelect->currentText(); //stores "Test Name" in string
hide();
Testwindow = new testwindow(this);
Testwindow->show();
}

The simplest way to do this is, as suggested in the comments, to pass the variable as parameter in the constructor of the class Testwindow. Then you can save the value of the string in a private variable in your Testwindow class and do whatever you want with it.
testwindow.h
class Testwindow : public QMainWindow
{
Q_OBJECT
public:
explicit Testwindow(QString text, QWidget *parent = nullptr);
signals:
private:
QString comboBoxText;
};
testwindow.cpp
Testwindow::Testwindow(QString text, QWidget *parent) : QMainWindow(parent)
{
comboBoxText = text; //now you can use comboBoxText in the rest of Testwindow class
}
mainwindow.cpp
void MainWindow::on_btnTestSelect_clicked()
{
QString str_TestSelect = ui->cmboTestSelect->currentText(); //stores "Test Name" in string
hide();
Testwindow *w = new Testwindow(str_TestSelect, this);
w->show();
}

Related

How to identify the pressed button in Qt C++?

I have 4 buttons on my main window. Each button opens its own window with its own data. How to identify the pressed button to open right window? For example: I press sales button and it opens a window that shows information about ticket sales.
Mainwindow ui
Here is my code from mainwindow h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <sales.h>
#include <theatres.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 button_pressed();
private:
Ui::MainWindow *ui;
sales *s;
theatres *t;
};
#endif // MAINWINDOW_H
And here is my code from mainwindow cpp:
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "build/sqlite/sqlite3.h"
#include <QtSql/QSqlDatabase>
#include <QTableView>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect((*ui).pushButton,SIGNAL(released()), this, SLOT(button_pressed()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::button_pressed()
{
s = new sales(this);
s -> show();
}
As Andy Newman already answered
the shortest solution is a lambda function
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QHBoxLayout *h_layout = new QHBoxLayout;
centralWidget()->setLayout(h_layout);
for(int c =1; c <= 10; c++)
{
QPushButton *button = new QPushButton(this); // create button
button->setText(QString::number(c)); // set button id
h_layout->addWidget(button); // add a button to the form
// lambda magic
/* connecting a button signal to a lambda function that captures a pointer to a
button and invokes an arbitrary type function. */
connect(button, &QPushButton::clicked, [this, button]() {
pressedButton(button->text());
});
}
}
void MainWindow::pressedButton(const QString &id_button)
{
qDebug("Pressed button: %ls", id_button.utf16());
}
MainWindow::~MainWindow()
{
delete ui;
}
#include "widget.h"
#include "./ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->btn_0,&QPushButton::clicked,this,&Widget::SlotButtonClicked);
connect(ui->btn_1,&QPushButton::clicked,this,&Widget::SlotButtonClicked);
connect(ui->btn_2,&QPushButton::clicked,this,&Widget::SlotButtonClicked);
connect(ui->btn_3,&QPushButton::clicked,this,&Widget::SlotButtonClicked);
}
Widget::~Widget()
{
delete ui;
}
void Widget::SlotButtonClicked()
{
auto sender = this->sender();
if ( sender == ui->btn_0 ) {
// Click btn_0 to open widget0
} else if ( sender == ui->btn_1 ) {
// Click btn_1 to open widget1
} else if ( sender == ui->btn_2 ) {
// Click btn_2 to open widget2
} else if ( sender == ui->btn_3 ) {
// Click btn_3 to open widget3
}
}
If you can use Qt Designer, the best way to do this is to click with button right on the QPushButton (On .ui file in Qt Designer) and click to "Go to Slot", this will create a private slot to this button! In the header file will create the definition, like this:
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
And in the source file (.cpp) will create the "function" clicked pushButton:
void MainWindow::on_pushButton_clicked()
{
}
void MainWindow::on_pushButton_2_clicked()
{
}
void MainWindow::on_pushButton_3_clicked()
{
}
void MainWindow::on_pushButton_4_clicked()
{
}
Inside of the "function" in .cpp, you put the task that you want this button to do, in this case, to open a new window!
When you click "go to slot" in another button, will create another private slot with the respective number (If is the second QPushButton that you create, the private slot will be called by pushButton_2).
The usual way to do this would be to connect the 4 different buttons to 4 different slots. It looks like you are using QtDesigner so that shouldn't be an issue.
If you were generating an array of buttons at run time you'd run into problems and would need a different solution. You could try something like this to pass an array index to the function, for example:
connect(button[x], &QPushButton::clicked, this, [this, x]() { button_pressed(x); });
Or you could do it the Qt way, which would be to call ::setProperty to store data in the button, and then retrieve it from the event, but it's so esoteric that I can't actually remember how to do that...

How to get QString from one window to another window, via pressing a button in a 3rd window

New to C++ and Qt as part of a research project (biology) and have been struggling with presumably some quite simple stuff. I'd really appreciate someone's help.
I'm working with a GUI for a pre-existing programme and I'm trying to transfer a QString variable from the QLineEdit of one of the windows (inputform), to the QLineEdit of a second window (output form).
The bit I'm stuck with is that I need the output form to appear, with it's LineEdit pre-populated, when I click a button on a third window (filedialog).
Problem:
At start up --> two windows appear: filedialog and inputform.
User enters data into inputform's QLineEdit
User presses 'transferButton' on filedialog window
On button press --> outputform appears, with a QLineEdit pre-populated with the user's data (from the inputform).
I assume the problem is of the getter/setter variety and my variable is probably going out of scope, but I've tried following lots of similar examples but can't make it work.
Thanks in advance.
Here's my code:
Main.cpp
#include "filedialog.h"
#include "inputform.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FileDialog w;
InputForm w2;
w.show();
w2.show();
return a.exec();
}
filedialog.h
#ifndef FILEDIALOG_H
#define FILEDIALOG_H
#include <QDialog>
namespace Ui {
class FileDialog;
}
class FileDialog : public QDialog
{
Q_OBJECT
public:
explicit FileDialog(QWidget *parent = nullptr);
~FileDialog();
void setFileName();
QString getFileName();
private slots:
void on_transferButton_clicked();
private:
Ui::FileDialog *ui;
QString fileName;
};
#endif // FILEDIALOG_H
filedialog.ccp
#include "filedialog.h"
#include "ui_filedialog.h"
#include "inputform.h"
#include "ui_inputform.h"
#include "outputform.h"
#include "ui_outputform.h"
FileDialog::FileDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::FileDialog)
{
ui->setupUi(this);
}
FileDialog::~FileDialog()
{
delete ui;
}
void FileDialog::setFileName()
{
InputForm *inputform = new InputForm;
fileName = inputform->ui->inputLineEdit->text();
}
QString FileDialog::getFileName()
{
return fileName;
}
void FileDialog::on_transferButton_clicked()
{
setFileName();
OutPutForm *outputform = new OutPutForm;
outputform->ui->outputLineEdit->setText(getFileName());
outputform->show();
}
inputform.h
#ifndef INPUTFORM_H
#define INPUTFORM_H
#include <QWidget>
namespace Ui {
class InputForm;
}
class InputForm : public QWidget
{
Q_OBJECT
public:
explicit InputForm(QWidget *parent = nullptr);
~InputForm();
Ui::InputForm *ui;
};
#endif // INPUTFORM_H
inputform.ccp
#include "inputform.h"
#include "ui_inputform.h"
InputForm::InputForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::InputForm)
{
ui->setupUi(this);
}
InputForm::~InputForm()
{
delete ui;
}
outputform.h
#ifndef OUTPUTFORM_H
#define OUTPUTFORM_H
#include <QWidget>
namespace Ui {
class OutPutForm;
}
class OutPutForm : public QWidget
{
Q_OBJECT
public:
explicit OutPutForm(QWidget *parent = nullptr);
~OutPutForm();
Ui::OutPutForm *ui;
};
#endif // OUTPUTFORM_H
outputform.ccp
#include "outputform.h"
#include "ui_outputform.h"
OutPutForm::OutPutForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::OutPutForm)
{
ui->setupUi(this);
}
OutPutForm::~OutPutForm()
{
delete ui;
}
Thank you for your brief pointer.
After some playing around:
Setup mainwindow (or in my case main dialog window). Generate inputform instance, connect button to inputform.
FileDialog::FileDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::FileDialog)
{
ui->setupUi(this);
InputForm *inputForm = new InputForm;
connect(ui->transferButton,SIGNAL(clicked()),inputForm,SLOT(getLineEditTextFunc()));
inputForm->show();
}
FileDialog::~FileDialog()
{
delete ui;
}
void FileDialog::on_transferButton_clicked()
{
}
Then from the input form:
Define a function to get the input form's LineEdit text (fileName); and then also generate an output form and populate it's LineEdit with the fileName variable.
InputForm::InputForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::InputForm)
{
ui->setupUi(this);
}
InputForm::~InputForm()
{
delete ui;
}
void InputForm::getLineEditTextFunc()
{
fileName = this->ui->inputLineEdit->text();
OutPutForm *outputform = new OutPutForm;
outputform->ui->outputLineEdit->setText(fileName);
outputform->show();
}

Pass variable from mainwindow to another qt c++ forms

I want to pass three strings (cellTitle,cellPoem,cellGroup) from mainwindows to another dialog. I know when i initiate the second form the values become zeros. I read somewhere it's possible with slots but i don't know how.
mainwindows.h
public:
QString cellTitle,cellPoem,cellGroup;
mainwindows.cpp
void MainWindow::on_tableView_pressed(const QModelIndex &index)
{
cellText = ui->tableView->model()->data(index).toString();
QSqlQuery * qry2 = new QSqlQuery(mydb);
qry2->prepare("select * from Poems where Title='"+cellText+"'");
qry2->exec();
while(qry2->next()){
cellTitle = qry2->value(1).toString();
cellPoem = qry2->value(2).toString();
cellGroup = qry2->value(3).toString();
ui->textEdit->setText(qry2->value(2).toString());
}
}
void MainWindow::on_btnUpdate_clicked()
{
frmUpdate frmupdate;
frmupdate.setModal(true);
frmupdate.exec();
}
frmupdate.cpp
#include "frmupdate.h"
#include "ui_frmupdate.h"
#include <mainwindow.h>
frmUpdate::frmUpdate(QWidget *parent) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
MainWindow mainwindow;
ui->lineEdit->setText(mainwindow.cellTitle);
ui->lineEdit_2->setText(mainwindow.cellGroup);
ui->textEdit->setText(mainwindow.cellPoem);
}
frmUpdate::~frmUpdate()
{
delete ui;
}
void frmUpdate::on_btnUpdate_clicked()
{
}
void frmUpdate::on_pushButton_2_clicked()
{
this->close();
}
frmUpdate::frmUpdate(QWidget *parent) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
MainWindow mainwindow;
You here have created a new, temporary MainWindow instance only with default constructor being called. Of course, this new instance is then created with empty default texts:
ui->lineEdit->setText(mainwindow.cellTitle);
ui->lineEdit_2->setText(mainwindow.cellGroup);
ui->textEdit->setText(mainwindow.cellPoem);
}
Easiest now would be passing the original main window as parameter:
frmUpdate::frmUpdate(QWidget* parent, MainWindow* mainWindow) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
ui->lineEdit->setText(mainwindow->cellTitle);
ui->lineEdit_2->setText(mainwindow->cellGroup);
ui->textEdit->setText(mainwindow->cellPoem);
}
If the parent is the main window, you can simply cast:
frmUpdate::frmUpdate(QWidget* parent) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
MainWindow* mainWindow = qobject_cast<MainWindow*>(parent);
if(mainWindow)
{
ui->lineEdit->setText(mainwindow->cellTitle);
ui->lineEdit_2->setText(mainwindow->cellGroup);
ui->textEdit->setText(mainwindow->cellPoem);
}
else
{
// appropriate error handling
}
}
You might search the main window from parent as well:
for(;;)
{
MainWindow* mainWindow = qobject_cast<MainWindow*>(parent);
if(mainWindow)
{
ui->lineEdit->setText(mainwindow->cellTitle);
ui->lineEdit_2->setText(mainwindow->cellGroup);
ui->textEdit->setText(mainwindow->cellPoem);
break;
}
parent = parent->parent();
if(!parent)
{
// appropriate error handling
break;
}
}
All above assuming that MainWindow inherits from QObject...

Want to add pushbutton to setTimer and setText

I am newbie in GUI design. Here, in sending and receiving messages (float, integer values) using DDS (OpenSplice) I am trying to add a pushButton to my already existing labels(displaying some float values as shown below), so that after a clicking on the pushButton, I should be able to see data in my label.
I tried adding a push button with the help of Qt Network sender Example. Now I get the error undefined reference to 'MainWindow::on_pushButton_clicked() in the file moc_mainwindow.cpp while building the project.
fastsender.cpp
FastSender::FastSender(QLabel *x, QObject *parent) : QObject(parent)
{
wSend = x;
dataTimer = new QTimer(this);
emergency = new QPushButton(tr("Emergency"));
buttonBox = new QDialogButtonBox;
buttonBox->addButton(emergency,QDialogButtonBox::ActionRole);
connect(emergency, SIGNAL(clicked()), this, SLOT(startsending()));
connect(dataTimer, SIGNAL(timeout()), this, SLOT(walk()));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(buttonBox);
}
void FastSender::startsending()
{
emergency->setEnabled(false);
dataTimer->start(100); // Interval 0 means to refresh as fast as possible
}
int FastSender::walk()
{
msg->value= i+0.1;
snprintf (buf, MAX_MSG_LEN, "Message no. %d", i);
cout << "Writing message: \"" << msg->value << "\"" << endl;
status = talker->write(*msg, userHandle);
QString s= QString::number(msg->value, 'f',8);
wSend->setText(s);
}
fastsender.h
class FastSender : public QObject
{
Q_OBJECT
public:
explicit FastSender(QObject *parent = 0);
FastSender(QLabel *x, QObject *parent = 0);
~FastSender();
signals:
private:
QTimer* dataTimer;
QLabel *wSend;
DDS::DomainParticipantFactory_var dpf;
DDS::DomainParticipant_var parentDP;
DDS::Topic_var signalTopic;
DDS::DataReader_var parentReader;
DDS::DataWriter_var parentWriter;
fw::signalSeq_var msgSeq;
char * signalTypeName;
fw::signalDataWriter_var talker;
fw::signal *msg;
DDS::InstanceHandle_t userHandle;
DDS::Publisher_var fwPublisher;
int alpa;
QPushButton *emergency;
QDialogButtonBox *buttonBox;
public slots:
int walk();
int hello();
void startsending();
};
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
fwdds = new FastWanDDS(ui->label);//receiving values are displayed in label
fwdds1 = new FastSender(ui->label_2);//Sending values are displayed in label_2
}
mainwindow.h
Ui::MainWindow *ui;
QTimer* timer;
int counter;
FastWanDDS *fwdds;
FastSender *fwdds1;
Any Help Appreciated.
Note: Only snippets of the code presented
I got it to work this way. Does this work for you?
mainwindow.cpp
#include "mainwindow.h"
#include "fastsender.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel* label = new QLabel("unchanged");
FastSender* fs = new FastSender(label);
setCentralWidget(fs);
}
MainWindow::~MainWindow()
{
}
fastsender.h
#ifndef FASTSENDER_H
#define FASTSENDER_H
#include <QLabel>
#include <QTimer>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QHBoxLayout>
class FastSender : public QWidget
{
Q_OBJECT
public:
FastSender(QLabel* label, QWidget* parent = 0)
: QWidget(parent)
, _label(label)
, _timer(new QTimer)
, _emergency(new QPushButton(tr("Emergency")))
, _bbox(new QDialogButtonBox)
{
_bbox->addButton(_emergency, QDialogButtonBox::ActionRole);
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(_label);
layout->addWidget(_bbox);
setLayout(layout);
connect(_emergency, SIGNAL(clicked(bool)), this, SLOT(startsending()));
connect(_timer, SIGNAL(timeout()), this, SLOT(walk()));
}
public slots:
void startsending()
{
_emergency->setEnabled(false);
_timer->start(100);
}
int walk()
{
_label->setText("changed");
_emergency->setEnabled(true);
}
private:
QLabel* _label;
QTimer* _timer;
QPushButton* _emergency;
QDialogButtonBox* _bbox;
};
#endif // FASTSENDER_H

Embed a QWebEngineView process inside QTabWidget

I'm trying to integrate a QWebEngineView widget that runs as a separate process(QProcess) inside a QTabWidget page. So far the QWebEngineView process is being started properly but its showing the webpage in a separate window instead of showing it inside the QTabWidget in the MainWindow application.
This is the Widget that is being added to the QTabWidget.
BrokersTerminal.h
class BrokersTerminal : public QWidget
{
Q_OBJECT
public:
explicit BrokersTerminal(QWidget *parent = 0);
~BrokersTerminal();
void startTerminal();
public slots:
void brokersTerminalStarted();
private:
Ui::BrokersTerminal *ui;
QProcess *brokers_process;
QString brokers_program_path;
QStringList arguments;
};
BrokersTerminal.cpp
BrokersTerminal::BrokersTerminal(QWidget *parent) :
QWidget(parent),
ui(new Ui::BrokersTerminal)
{
ui->setupUi(this);
brokers_process = new QProcess( this );
brokers_program_path = QApplication::applicationFilePath();
arguments << "--b";
connect( brokers_process, &QProcess::started, this , &BrokersTerminal::brokersTerminalStarted );
}
BrokersTerminal::~BrokersTerminal()
{
delete ui;
}
void BrokersTerminal::startTerminal()
{
brokers_process->start( brokers_program_path, arguments );
brokers_process->waitForStarted();
}
void BrokersTerminal::brokersTerminalStarted()
{
qDebug() << "Brokers terminal started";
}
This is the WebView Widget that is responsible for displaying the brokers website.
BrokersWebWidget.h
class BrokersWebWidget : public QWidget
{
Q_OBJECT
public:
explicit BrokersWebWidget(QWidget *parent = 0);
~BrokersWebWidget();
private:
Ui::BrokersWebWidget *ui;
QUrl brokers_url;
QWebEngineView *web_browser;
};
BrokersWebWidget.cpp
BrokersWebWidget::BrokersWebWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::BrokersWebWidget)
{
ui->setupUi(this);
brokers_url = "https://siteofbrokersapi.com/";
web_browser = new QWebEngineView( this );
web_browser->load( brokers_url );
}
BrokersWebWidget::~BrokersWebWidget()
{
delete ui;
}
Right now this BrokersWebWidget starts properly as a separate process but it opens in a separate window , but how can this be added in the BrokersTerminal Widget ?
Please let me know of any possible solutions. Thanks.
You cannot embed a widget running in one process into a window run in another. QWidgets can only work with widgets run in the GUI thread in the same process.