I have signal in my MainWindow to emit a number thats in a line edit. When I click a button to open the dialog, I want that number to be copied to the line edit in the dialog. I can't get it to connect. I can see the signal is emitting with qDebug. Am I connecting it wrong or in the wrong place? I have tried many ways. Here are my code snippets.
Mainwindow
//My MainWindow
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
//This is the number I am trying to send to the dialog
ui->checkingAmount->setText(QString::number(1000.00, 'f', 2));
ui->checkingAmount->setReadOnly(true);
}
//Emit the data here
void MainWindow::on_transferButton_clicked() {
transferWindow = new TransferWindow(this);
transferWindow->show();
//trying to emit the data
QString data =ui->checkingAmount->text();
emit shareCheckingData(data);
qDebug()<<"emitting mainwin amount";
}
Dialog
//My Dialog
TransferWindow::TransferWindow(QWidget *parent) : QDialog(parent),ui(new Ui::TransferWindow) {
ui->setupUi(this);
//I have tried several variations of this
//mainWindow = new MainWindow();
connect(mainWindow, SIGNAL(shareCheckingData(QString)),this, SLOT(getAmountFromMainWin(QString)));
}
//Here is the connecting slot to get the data from main window
void TransferWindow::getAmountFromMainWin(QString n) {
float CheckTotal = n.toFloat();
ui->checkingAmount->setReadOnly(true);
ui->checkingAmount->setText(QString::number(CheckTotal));
qDebug()<<"setting amount";
}
How can I get this to connect? I read through many posts and it did not solve the problem. Thanks.
I notice in the comments of your code that you intend to create an instance of MainWindow and try to connect to this instance, that is a new instance different from the previous one so you will not be able to get it.
First we must create the instance and then connect it, that we can do in the constructor.
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->checkingAmount->setText(QString::number(1000.00, 'f', 2));
ui->checkingAmount->setReadOnly(true);
transferWindow = new TransferWindow(this);
connect(this, &MainWindow::shareCheckingData, transferWindow, &TransferWindow::getAmountFromMainWin);
//old style
//connect(this, SIGNAL(shareCheckingData(QString)), transferWindow, SLOT(getAmountFromMainWin(QString)));
}
void MainWindow::on_transferButton_clicked()
{
//trying to emit the data
QString data =ui->checkingAmount->text();
emit shareCheckingData(data);
qDebug()<<"emitting mainwin amount";
transferWindow->show();
}
TransferWindow.cpp
TransferWindow::TransferWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::TransferWindow)
{
ui->setupUi(this);
}
void TransferWindow::getAmountFromMainWin(QString n)
{
float CheckTotal = n.toFloat();
ui->checkingAmount->setReadOnly(true);
ui->checkingAmount->setText(QString::number(CheckTotal));
qDebug()<<"setting amount";
}
Related
Can you think of a reason why this second scenario not working?
I have signal connection in two windows , Settings and Patients
In Settings:
Settings::Settings( QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Settings)
{
ui->setupUi(this);
connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler);
...
}
api is global instance of a class.
And in Patients:
Patients::Patients( QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Patients)
{
ui->setupUi(this);
connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);
}
Situation1 - Working
I construct both Settings and Patients window from Main
#include <QApplication>
tetra_grip_api api;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
api.openSerialPort();
QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData()));
Settings w(nullptr); //---->this behaves right
Patients v(nullptr); //---- >this behaves right
v.show();
w.show();
return a.exec();
}
By working I mean , both the slots are being called , and QLabel set text accordingly
Situation 2 - Not working
I call Patients from Settings:
void Settings::on_pushButton_patients_clicked()
{
this->close();
stagetwo = new Patients(this);
stagetwo -> show();
}
where stagetwo is public
public:
Settings(QString,QWidget *parent = nullptr);
~Settings();
Patients *stagetwo;
Here Settings works just fine (slot being called) but Patients::eventhandlerTwo is not being called at all.
EDIT (Found the bug)
It's bit late to understand that I need to call a method in the API (battery_percentage) to emit signal tetraGripEvent ( bettery_percentage will contact "battery register" in the device and this will force API to emit signal)
basically I need to do this on both Settings and Patients
#include "settings.h"
#include "ui_settings.h"
Settings :: Settings (QWidget *parent) : QMainWindow(parent)
QMainWindow(parent)
, ui(new Ui::Settings )
{
ui->setupUi(this);
connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler);
...
tetra_grip_api::battery_percentage(); ------> calling this only emit the signal
}
and in Patients
#include "patients.h"
#include "ui_patients.h"
Patients::Patients(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Patients)
{
ui->setupUi(this);
connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);
...
tetra_grip_api::battery_percentage();
}
As per Qt documentation for QWidget::close(), which QMainWindow is being inherited from:
The QApplication::lastWindowClosed() signal is emitted when the last
visible primary window (i.e. window with no parent) with the
Qt::WA_QuitOnClose attribute set is closed. By default this attribute
is set for all widgets except transient windows such as splash
screens, tool windows, and popup menus.
So, in the second scenario, when you set the parent of Patients to a Settings instance, you should expect an undefined behavior like this. Because by calling Settings::close() should delete Settings and quit the application when the call returns to the event loop. You can explicitly change it by :
Settings::Settings( QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Settings)
{
ui->setupUi(this);
this->setAttribute(Qt::WA_QuitOnClose, false);
connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler);
...
}
You can also reparent both windows to another window.
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...
I have a QStackedWidget with a custom widget in it.
//mainwindow.h
private:
CentralWidget m_centralWidget;
//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->stackedWidget->addWidget(&m_centralWidget);
}
Now i want to create a QSplitter, fill the Splitter with content and add this Splitter to the StackedWidget.
CentralWidget::CentralWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::CentralWidget)
{
ui->setupUi(this);
connect(ui->pbAddSplit, SIGNAL(pressed()), this, SLOT(addSplit()));
}
void CentralWidget::addSplit()
{
QWidget* parent = parentWidget();
QStackedWidget* stackedWidget = qobject_cast<QStackedWidget*>(parent);
if(!stackedWidget) {
return;
}
QSplitter* splitter = new QSplitter(Qt::Vertical);
splitter->addWidget(new QLabel("Banana"));
splitter->addWidget(this);
int nIndex = stackedWidget->addWidget(splitter);
stackedWidget->setCurrentIndex(nIndex);
}
The result should be a QLabel("Banana") as one Widget of the splitter and the CentralWidget as the other splitter-widget.
But i just get the QLabel("Banana") - SplitterHandle and the CentralWidget got lost somehow...
splitter->addWidget(this) is obviously wrong...
Replacing it with splitter->addWidget(new QLabel("Cherry")) will result in a correct SplitterWidget...
The problem seems to be the parenting, but i cant figure it out.
Any suggestions would be most welcome!
If I create my QDialog and show it modal with exec() everything works fine, but I need this no modal!
With show() the Dialog is empty!
ProgramLoading *programLoading = new ProgramLoading();
programLoading->show();
// some code
programLoading->done(0);
Constructor
ProgramLoading::ProgramLoading(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
setWindowFlags( Qt::CustomizeWindowHint ); // remove window border
}
Don't think something with Dialog code is wrong because it works with exec()!
Any hints? Thank you!
PS: I'm using QT plugin for VisualStudio 2008
mw (Default with Window Decoration):
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
sd = new SplashDialog();
sd->show();
QTimer::singleShot(10000,this,SLOT(closeSplashDialog()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::closeSplashDialog()
{
sd->close();
delete sd;
}
splash (UI having Label and Button):
SplashDialog::SplashDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SplashDialog)
{
ui->setupUi(this);
setWindowFlags( Qt::CustomizeWindowHint );
}
SplashDialog::~SplashDialog()
{
delete ui;
}
Splash Dialog opens and is being closed 10 seconds later as intended
This is the main window so far and the second window is a dialog window. How do I get the text from a textbox on window2 when it closes?
Thanks.
#include "mainwindow.h"
#include "window2.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(closeProgram()));
connect(ui->openWindowBtn, SIGNAL(clicked()), this, SLOT(openSecondWindow()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::openSecondWindow()
{
Window2 w2;
w2.exec();
}
void MainWindow::closeProgram()
{
close();
}
Found Solution
All I had to do is create a getString() function in the Window2 class to retreive the text from ui->...
QString Window2::getString()
{
return ui->textEdit->text();
}
Look at your .ui file in designer (or the resulting generated file from the uic), and access the QLineEdit object by name (the same way you connect that signal). You can retrieve the text with the lineEdit::text() accessor.