As per a tutorial I'm following, I'm placing functions that I would like to call in my widget under public: Q_SLOTS in mainwindow.h. When I open mainwindow.ui in design mode, then click edit->edit signals/slots, and left click on a button and drag to the window,I don't see an option to associate the signal I created with one of the functions I specified myself.
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();
public Q_SLOTS:
void SendBtnClicked();
void TypingChanged();
void LoginClicked();
void OnMessageReturn();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
If you want to connect the signal to your slot from there. you should add your slot to that slot list.
For Example, I write this slot in mainwindow.h
private slots:
void myExampleSlot();
that print something.
void MainWindow::myExampleSlot()
{
qDebug() << "I am here";
}
press Edit and then add your slot function :
then find this in the slots list and choose it.
out put :
Related
I have a MainWindow class which contain a QComboBox and a widget which is from another class. This second class contain a QCheckBox and a QComboBox. I want to use a signal to change the checkState of my QCheckBox and the string displayed in my QComboBox from my widget class when the string displayed in my QComboBox from my MainWindow has changed.
But I don't really understand which form my signal must have and how I can use it in my widget class.
MainWindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QComboBox>
#include "devices_left_widget.h"
#define STRING_DEVICE1 "DEVICE1"
#define STRING_DEFAULT ""
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = nullptr);
signals:
public slots:
void carte_OK();
protected:
QComboBox* carte_type_combo_box;
devices_left_widget* left_widget;
};
#endif // MAINWINDOW_H
device_left_widget.h :
#ifndef DEVICE_LEFT_WIDGET_H
#define DEVICE_LEFT_WIDGET_H
#include <QWidget>
#include <QCheckBox>
#include <QComboBox>
#define STRING_DEVICE1 "DEVICE1"
#define STRING_DEFAULT ""
class device_left_widget : public QWidget {
Q_OBJECT
public:
explicit device_left_widget(QWidget* parent = nullptr);
signals:
public slots:
protected:
QGridLayout* main_grid_layout;
QCheckBox* device_checkbox;
QComboBox* device_type_combo_box;
};
#endif // DEVICES_LEFT_WIDGET_H
Let's call your widget's name container. We want to connect QComboBox's currentTextChanged(const QString &text) signal to the widget, so we create a slot that corresponds to the signal, let it be chosenTextChanged(const QString& text). We connect them inside MainWindow constructor:
connect(ui->comboBox, SIGNAL(currentTextChanged(const QString &)),
ui->container, SLOT(chosenTextChanged(const QString &)));
And inside your container class, define the slot as public:
public slots:
void chosenTextChanged(const QString &text) {
//change your QCheckBox's state and
//change your QComboBox's text
}
I'm trying to connect two frames with a custom signal but I'm not really getting it.
This code is just an example of what im trying to do in my program, my objective is to transfer data between frames.
Files:
(sender)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
signals:
void send();
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void on_pushButton_clicked();
};
#endif // MAINWINDOW_H
On "mainwindow.cpp" I've got the void on_pushButton_clicked() that emits the signal and shows the new frame:
private slot void:
void MainWindow::on_pushButton_clicked()
{
emit send();
Dialog sw;
sw.setModal(true);
sw.exec();
}
(receiver):
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QDebug>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void receive();
private:
Ui::Dialog *ui;
int a;
};
#endif // DIALOG_H
and the .cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include "mainwindow.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
a=0;
MainWindow w;
connect(&w, SIGNAL(send()), this, SLOT(receive()));
qDebug() << a;
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::receive(){
qDebug() << "ola";
a++;
}
Conclusion:
So basicly the function Dialog doesn't print the qDebug(), and 'a' is still 0, so I conclude that the connection isn't set/executed.
Thanks all,
Best regards,
Dylan Lopes.
edit: Wrote a conclusion on the end of the post.
Consider the code in your Dialog constructor...
MainWindow w;
connect(&w, SIGNAL(send()), this, SLOT(receive()));
This creates a locally scoped MainWindow on the stack and connects its send() signal to the Dialog's receive() slot. But the MainWindow -- and, hence, the connection -- will be destroyed as soon as the Dialog constructor has completed.
In addition, looking at MainWindow::on_pushButton_clicked...
void MainWindow::on_pushButton_clicked()
{
emit send();
Dialog sw;
sw.setModal(true);
sw.exec();
}
You emit the send() signal before constructing the Dialog.
I don't really know enough about what you're trying to achieve to provide a definitive answer, but in the interests of getting some kind of signal/slot interaction you might want to do the following: change the Dialog constructor to...
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
a=0;
qDebug() << a;
}
And change MainWindow::on_pushButton_clicked to...
void MainWindow::on_pushButton_clicked()
{
Dialog sw;
connect(this, &MainWindow::send, &sw, &Dialog::receive);
emit send();
sw.setModal(true);
sw.exec();
}
That should at least result in Dialog::receive being invoked and you can work from there.
Connection between a signal and a slot doesn't mean that the signal function will be triggered.
You still need to emit your signal so that a gets updated.
Creating an empty slot isn't working either, as slots are the receiving point of a signal. In this case, on_pushButton_clicked() gets triggered whent he push button is clicked. This doesn't trigger send unless you call EMIT(send()) (IIRC, you emit a signal with EMIT, is that still the case?).
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.
There are two files:
mainwindow.cpp and editorplain.cpp
editorplain.cpp is dialog as widget.
Problem: Send text data to label on another dialog.
mainwidnow.cpp
Action on triggered from menu call a new dialog:
er will return string from mainwindow.
void MainWindow::on_actionRoot_files_triggered()
{
QString er = ui->selected_filename->text();
Editorplain editorplainwidget;
// HERE IS WHAT I WANT SEND A DATA TO ANOTHER DIALOG `editorplain`
editorplainwidget.exec();
}
When opening dialog I want a grab data from string er:
Editorplain::setData(myType myData)
{
ui->label_2->setText(myData.textForEdit);
}
Let's explain my problem. On mywindow I have a string er which returns some string as result. This er should send on dialog editorplain and set as label for example: ui->label->setText(er). Label is QLabel made on QDialog.
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 slots:
void on_actionOpen_triggered();
void on_actionExit_triggered();
void on_actionRoot_files_triggered();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
editorplain.cpp file:
#include "editorplain.h"
#include "ui_editorplain.h"
#include "mainwindow.h"
Editorplain::Editorplain(QWidget *parent) :
QDialog(parent),
ui(new Ui::Editorplain)
{
ui->setupUi(this);
// SHOULD PASS ON THIS CONTRUCTOR?
}
Editorplain::~Editorplain()
{
delete ui;
}
Editorplain::setData(myType myData)
{
ui->label_2->setText(myData.textForEdit);
}
If its a custom QDialog just make the function setData() public . That way you can call the function from MainWindow passing your string before showing the dialog. You do not then need to pass anything through the constructor.
Something like in editorplain.h
public:
void setData(const QString &labelText);
and editorplain.cpp
void Editorplain::setData(const QString &labelText) {
ui->label_2->setText(labelText);
}
Now in mainwindow.cpp
void MainWindow::on_actionRoot_files_triggered()
{
QString er = ui->selected_filename->text();
Editorplain editorplainwidget;
editorplainwidget.setData(er);
editorplainwidget.exec();
}
You can just pass that string to Editorplain constructor, if that isn't a problem.
That is, creating slots by right-clicking a widget and selecting "go to slot...".
Example 1, this works:
#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;
};
#endif // MAINWINDOW_H
This doesn't, because apparently the designer looks for Ui::MainWindow* and completely freaks out if it can't find it (getting "The class containing 'Ui::MainWindow' could not be found ...")
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <memory>
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
std::unique_ptr<Ui::MainWindow> ui;
};
#endif // MAINWINDOW_H
I'm basically looking for a way to tell Qt "Yes, I really mean that class. I know it doesn't contain a Ui::MainWindow*, it's ok everything will be alright...". Unless I'm wrong and the class actually needs this to be a plain pointer for some reason.
"The class containing 'Ui::MainWindow' could not be found ..." issue happens when QT creator can't find your "mainwindow.cpp" file to place the slot function definition.
Make sure your mainwindow.h has the following as a private variable:
Ui::MainWindow *ui;
And following include is in your mainwindow.cpp file:
#include "ui_mainwindow.h"
If this doesn't work, there may be a bug with your QT creator. Try updating your software.