Сигналы и слоты в QT на С++
Пытаюсь разобраться с системой сигналов и слотов. Нишиша не получается... По задумке Кнопка созданная в классе Button, должна посылать сигнал в слот confirm_window_open в классе Window... Все работает только в том случае если confirm_window_open сделать static... Везде во всех примерах все вроде так же...
#ifndef TEST_H
#define TEST_H
#endif // TEST_H
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QGridLayout>
#include <QFont>
#include <iostream>
class Window :public QObject{
Q_OBJECT
public:
QWidget window;
QGridLayout* grid = new QGridLayout;
Window(int W, int H, QString title){
window.setMinimumSize(W, H);
window.setWindowTitle(title);
window.setLayout(grid);
}
public slots:
void confirm_window_open(){
std::cout << "DONE!" << std::endl;
}
};
class Button :public QObject{
Q_OBJECT
public:
QFont font;
Button(QString text, QWidget &window, QGridLayout &grid, int row, int column){
QPushButton* button = new QPushButton(&window);
(*button).setText(text);
(*button).setMinimumHeight(50);
(*button).setStyleSheet("padding-left: 10px; padding-right: 10px;");
font.setFamily("Arial");
font.setPixelSize(15);
(*button).setFont(font);
grid.addWidget(button, row, column);
connect(button, &QPushButton::clicked, window, &Window::confirm_window_open);
}
};
class Main_window :public Window{
Q_OBJECT
public:
Main_window() :Window(2000, 800, "Дневник"){
Button button1("Создать дневник", window *grid, 2, 13);
}
};
Ответы (1 шт):
Автор решения: maestro
→ Ссылка
Вот ваш код с минимальными изменениями, приведённый в работоспособное состояние. Весь код можно скопировать в файл main.cpp, скомпилировать и запустить.
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QGridLayout>
#include <QFont>
#include <iostream>
class Window :public QObject{
Q_OBJECT
public:
QWidget window;
QGridLayout* grid = new QGridLayout;
Window(int W, int H, QString title){
window.setMinimumSize(W, H);
window.setWindowTitle(title);
window.setLayout(grid);
}
public slots:
void confirm_window_open(){
std::cout << "DONE!" << std::endl;
}
};
class Button : public QObject{
Q_OBJECT
public:
QFont font;
// Здесь вы передаёте вторым параметром ссылку на объект типа QWidget
// и пытаетесь подключится к его слоту confirm_window_open.
// Но у типа QWidget нет такого слота! Он есть у типа Window.
// Скорее всего, вы имели в виду именно его.
// Поэтому поменяем тип второго параметра.
Button(QString text, Window &window, QGridLayout &grid, int row, int column){
QPushButton* button = new QPushButton(&window.window);
(*button).setText(text);
(*button).setMinimumHeight(50);
(*button).setStyleSheet("padding-left: 10px; padding-right: 10px;");
font.setFamily("Arial");
font.setPixelSize(15);
(*button).setFont(font);
grid.addWidget(button, row, column);
// Параметр window имеет тип ссылки, а функция connect
// ожидает тип указателя. Поэтому преобразуем ссылку в указатель.
connect(button, &QPushButton::clicked, &window, &Window::confirm_window_open);
}
};
class Main_window :public Window{
Q_OBJECT
Button button1;
public:
Main_window() :
Window(2000, 800, "Дневник"),
// Здесь вы передавали вторым параметром объект window,
// который имеет тип QWidget и не имеет слота
// confirm_window_open. Так как мы поменяли сигнатуру
// конструктора Button, изменим вызов здесь:
// передадим вторым параметром текущий объект, у которого
// есть слот confim_window_open.
// Кроме того, у вас кнопка была локальным объектом
// этого конструктора, и поэтому она была бы уничтожена
// сразу после завершения её выполнения.
// Поэтому перенесём её в класс.
button1("Создать дневник", *this, *grid, 2, 13)
{
}
};
// Ну и сводим всё воедино.
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Main_window main_window;
main_window.window.show();
return app.exec();
}
#include "main.moc"