Qt connect mainwindow and dialog using signal and slot - qt

I am trying to connect mainwindow and dialog using signal and slot. I am very new to qt. I have a lineEdit and a pushButton in mainwindow.ui, a lineEdit in dialog.ui. And I have those very basic code:
mainwindow.h:
signals:
void sendString(QString);
mainwindow.cpp:
void MainWindow::on_pushButton_clicked()
{
Dialog *mDialog = new Dialog(this);
emit sendString(ui->lineEdit->text());
connect(this, SIGNAL(sendString(QString)), mDialog, SLOT(showString(QString)));
mDialog->show();
}
dialog.h:
private slots:
void showString(QString);
dialog.cpp:
void Dialog::showString(QString str)
{
ui->lineEdit->setText(str);
}
But after I clicked the pushButton, the dialog showed, but nothing changed in the lineEdit.I hope I explain this clearly enough?
Can someone explain to me why and how to solve this? Thanks.

emit signal after connect
void MainWindow::on_pushButton_clicked()
{
Dialog *mDialog = new Dialog(this);
connect(this, SIGNAL(sendString(QString)), mDialog, SLOT(showString(QString)));
mDialog->show();
emit sendString(ui->lineEdit->text());
}

You have to create the connection before the emit.
But in your case you dont need the signal of the of the mainwindow at all. You invoke the showString method directly.

Related

QTextEdit refresh after setText()/insertPlainText()

I have a QTextEdit widget in a private slot, which I update regularly with setText() and insertPlainText().
I have found that setText()/insertPlainText() does not update the QTextEdit widget immediately. Instead, the QTextWidget is updated when the slot function returns. To test this, I have put a sleep() just after the setText()/insertPlainText().
class MyWindow : public Widget
{
MyWindow()
{
my_button = new QPushButton(this);
my_edit = new QTextEdit(this);
connect(my_button,
&QPushButton::clicked,
this,
&MyWindow::my_callback);
}
private slots:
void my_callback()
{
my_edit->setText("sample text");
// nothing happens; the QTextEdit
// widget does not show "sample text"
sleep(10);
// the QTextEdit widget will show
// "sample text" AFTER the sleep,
// when my_callback returns.
}
private:
QPushButton* my_button;
QTextEdit* my_edit;
}
This is a problem for me because I need to print a message in my QTextEdit widget BEFORE launching a time-consuming process (using QProcess). Currently, this message is not being printed until after QProcess process has returned.
Does anyone know how I can get the QTextEdit widget to show its contents right after setText()/insertPlainText()?
Using Qt5 on Fedora 29.
Never execute a task that consumes a lot of time in the GUI thread. In general, the solution is to execute that task in another thread, but in your case it indicates that you use QProcess, so I assume that you are using one of the methods waitForFinished(), waitForStarted() or waitForReadyRead(), instead you should use the signals:
#include <QtWidgets>
class Widget: public QWidget{
Q_OBJECT
public:
Widget(QWidget *parent=nullptr):
QWidget(parent)
{
button.setText("Press me");
QVBoxLayout *lay = new QVBoxLayout{this};
lay->addWidget(&button);
lay->addWidget(&textedit);
connect(&button, &QPushButton::clicked, this, &Widget::onClicked);
connect(&process, &QProcess::readyReadStandardError, this, &Widget::onReadyReadStandardError);
connect(&process, &QProcess::readyReadStandardOutput, this, &Widget::onReadAllStandardOutput);
}
private Q_SLOTS:
void onClicked(){
textedit.setText("sample text");
process.start("ping 8.8.8.8");
}
void onReadyReadStandardError(){
textedit.append(process.readAllStandardError());
}
void onReadAllStandardOutput(){
textedit.append(process.readAllStandardOutput());
}
private:
QPushButton button;
QTextEdit textedit;
QProcess process;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
I wonder if calling
QCoreApplication::processEvents()
right after the ->setText("sample text") would do the trick in your case.

Qt: Why doesn't my button get the signal?

Why didn't the button object get the sigKK() signal when the button was clicked?
When a signal is emitted, can all qt objects receive this signal?
The code is as follows:
class PushButton : public QPushButton
{
Q_OBJECT
signals:
void sigKK();
};
The PushButton class inherits from QPushButton, but doesn't connect signals and slots here. Is this right?
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(){
resize(400,200);
connect(this,SIGNAL(sigKK()),this,SLOT(showRecv1()));
button = new PushButton();
button->setText("Hello,All");
button->resize(40,15);
connect(button, SIGNAL(clicked()),this,SLOT(buttonCK()));
connect(button, SIGNAL(sigKK()),this,SLOT(showRecv2()));
//**I can connect sigKK signal with showRecv2 slot here ?****
button->show();
}
~MainWindow(){
}
signals:
void sigKK();
public slots:
void showRecv1(){
cout<<"recved 1"<<endl;
resize(100,100);
}
void showRecv2(){
cout<<"recved 2"<<endl;
button->setText(".....");
}
void buttonCK(){
emit sigKK();
cout<<"emited"<<endl;
}
private:
PushButton *button ;
};
#endif
When a signal is emitted, can all qt objects receive this signal ?
No. When a signal is emitted it is received only by QObjects with signals or slots connected to it.
Your MainWindow and your PushButton both have a signal with the same name... but they are still different signals. They are completely unrelated to each other. When MainWindow emits sigKK, that has no effect on PushButton's sigKK.
In your example, sigKK seems to be entirely unneccessary. Perhaps you could instead connect clicked() directly to the actions you want to perform?
connect(button, SIGNAL(clicked()),this,SLOT(showRecv1()));
connect(button, SIGNAL(clicked()),this,SLOT(showRecv2()));

Custom context menu connecting in Qt

I have a problem with connecting custom menu in QListWidget, the connect function returns false. Here is the code:
I've got some main window class called MainWindow. In its constructor I have this line
connect(ui->notesWidget, SIGNAL(customContextMenuRequested(QPoint &)),
this, SLOT(contextMenuforNotesArea(QPoint &)));
where notesWidget is mentioned QListWidget.
ContextMenuforNotesArea(QPoint &) is defined like this
class MainWindow : public QMainWindow
{
public slots:
void contextMenuforNotesArea(QPoint &pos);
};
void MainWindow::contextMenuforNotesArea(const QPoint &pos){
QMessageBox::information(this, "a", "the function has been finally called");
QMenu contextMenu(tr("Context menu"), this);
contextMenu.addAction(new QAction(tr("Hello"), this));
contextMenu.exec(mapToGlobal(pos));
}
I have also changed the property contextMenu in the listWidget to customContextMenu through form designer.
Change your SLOT signature as follows in the header file
void contextMenuforNotesArea(const QPoint &pos);
Also make sure, when you are doing the connection in the constructor, you do it after the calling of setupUi

Qt - two signals and modal dialog window

I have a QDialog based class.
I have one QEditLine *editLine and QButton *button.
I use clicked() signal of button. And editingFinished() signal of editLine.
When I change the text in the editLine and press the button firstly editingFinished() signal is emitted. In the slot method I call QMessageBox::question().
After that I can't receive clicked() signal of my button.
I tried to use Qt::QueuedConnection for connect method, but it does not help.
How to solve my problem?
I think the issue is that the event loop for the message box is blocking the main event loop so your button's signal is not emitted. But how do you plan to click the button anyway if you have a modal dialog open?
Here is the code:
Window::Window(QWidget *parent)
: QDialog(parent)
{
setupUi(this);
appPath = QApplication::applicationDirPath();
connect(pButton, SIGNAL(clicked()), this, SLOT(build()), Qt::QueuedConnection);
connect(pLineEdit, SIGNAL(editingFinished()), this, SLOT(pathChanged()), Qt::QueuedConnection);
}
void Window::pathChanged()
{
QString path = pLineEdit->text();
if(createPath(path))
updatePath(path);
}
bool Window::createPath(QString path)
{
if(!QDir(path).exists())
{
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, tr("Folder is not exist"), "Folder " + path + " is not exist. Do you want to create it?", QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes)
{
QDir dir;
dir.mkpath(path);
}
}
return true;
}
class Window : public QDialog, public Ui::GLConverterDialogUI
{
Q_OBJECT
public:
Window(QWidget *parent = 0);
~Window(void);
......
}
I have the same problem in another application. I use some library. I guess that this library use pressed() signal of QAbstractButton instead of clicked(). And when I call QFileDialog::getSaveFileName() after button is pressed it seems that mouseReleaseEvent() is also not called. So after closing of dialog button is still pressed and I have to send MouseButtonRealese event manually.
Maybe I should call dialog with some special parameters?

implement a progress dialog by QDialog

I'm using QT to implement some UI program.
In this program I need a progress dialog. I tried to use the build-in QProgressDialog, it works fine but in my case I need to confirm (with another dialog) when the "cancel button" is clicked.
In QProgressDialog once the cancel button is clicked, the progress dialog will be canceled, so, I tried to implement my own progress dialog (very simple, a dialog with progress bar). However, if I use my own progress dialog, there is some problems. It cannot be moved or clicked. Once I tried to move it and the dialog loss its focus, the progress bar won't update any more and it cannot gain the focus again. I tried to set different Modality, but either Qt::ApplicationModal or Qt::WindowModal has the same situation.
follows is my progress dialog class, if someone knows how to modify QProgressDialog to meet the confirm requirement or where is the problem in my code.
header:
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
void setRange(int minimum, int maximum);
void setValue(int value);
void setLabelText(QString labtext);
bool wasCanceled();
private:
Ui::Dialog *ui;
bool cancelStatus;
private slots:
void cancel();
};
Sourceļ¼š
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
cancelStatus = false;
ui->progressBar->setRange(0,1);
ui->progressBar->setValue(0);
//this->setWindowModality(Qt::WindowModal);
show();
}
Dialog::~Dialog(){
delete ui;
}
void Dialog::setRange(int minimum, int maximum){
ui->progressBar->setRange(minimum,maximum );
}
void Dialog::setValue(int value){
this->ui->progressBar->setValue(value);
}
void Dialog::setLabelText(QString labtext){
this->ui->label->setText(labtext);
}
void Dialog::cancel(){
// pop up the confirm dialog here
// cancelStatus = true if the confirm dialog is accepted, else do nothing .
}
bool Dialog::wasCanceled(){
return cancelStatus;
}
From the Qt Documentation: The signal QProgressDialog::canceled() is emitted when the cancel button is clicked and it is connected to the cancel() slot by default.
Did you try to connect the canceled signal to you own validation slot, and the cancel the dialog if the user confirm is choice?
Before, connecting your own slot, disconnect the canceled signal from the cancel slot using QObject::disconnect() : http://doc.qt.io/archives/qt-4.7/qobject.html#disconnect

Resources