Задать вопрос
EgoRusMarch
@EgoRusMarch
C++ Developer

Qt. Как использовать сигналы-слоты?

В общем не могу понять как сделать. Было бы неплохо, если бы Вы показали на этом примере как реализовать.
Я решил сделать конвертер масс из русских народных в СИшные.
Вот что я наговнокодил:
#include <QtWidgets>

int main(int argc, char *argv[])
{
    QApplication MyApp(argc,argv);

    // Меры масс
    QStringList ListWeight1, ListWeight2;

    // Ввод
    ListWeight1 << "БЕРКОВЕЦ"  << "ПУД"
                << "ФУНТ"      << "ЛОТ"
                << "ЗОЛОТНИК"  << "ДОЛЯ";

    // Вывод
    ListWeight2 << "ГРАММ"     << "КИЛОГРАММ"
                << "МИЛИГРАММ" << "ТОННА";

    // создать объект для хранения шрифта
    QFont Font[2];              // два шрифта
    Font[0].setPointSize(12);   // для заголовка
    Font[1].setPointSize(10);   // для текста

    // Базовый объект (окно)
    QWidget Base;                           // создать базовый объект
    Base.setWindowFlags(
               Qt::WindowCloseButtonHint);
    Base.setWindowTitle("Конвертер Масс");
    Base.setFixedSize(400,250);             // задать фиксированные ширину и высоту
    Base.show();                            // отобразить базовый объект

    // Заголовок
    QLabel Title(&Base);                    // создать объект-метку
    Title.resize(200,50);                   // задать размер объекта
    Title.move(100,0);                      // задать расположение объекта
    Title.setAlignment(Qt::AlignCenter);    // выровнивить содержиме по центру
    Title.setText("КОНВЕРТЕР МАСС");        // задать отображаемый текст         
    Title.setFont(Font[0]);                 // установить настройки текста для объекта
    Title.show();                           // отобразить объект-метку

    // Поле для значения веса (ввод)
    QLineEdit Input(&Base);
    Input.resize(150,30);
    Input.move(25,70);
    Input.setFont(Font[1]);
    Input.show();

    // Выпадающий список с единицами веса (ввод)
    QComboBox UnitInput(&Base);
    UnitInput.resize(150,30);
    UnitInput.move(225,70);
    UnitInput.setFont(Font[1]);
    UnitInput.addItems(ListWeight1);
    UnitInput.show();

    // Поле для значения веса (вывод)
    QLineEdit Output(&Base);
    Output.resize(150,30);
    Output.move(25,140);
    Output.setReadOnly(true);   // запрет редактирования
    Output.show();

    // Выпадающий список с единицами веса (вывод)
    QComboBox UnitOutput(&Base);
    UnitOutput.resize(150,30);
    UnitOutput.move(225,140);
    UnitOutput.setFont(Font[1]);
    UnitOutput.addItems(ListWeight2);
    UnitOutput.show();

    // Кнопка для вычисления
    QPushButton Button(&Base);
    Button.resize(100,30);
    Button.move(150,200);
    Button.setText("ВЫЧИСЛИТЬ");
    Button.setFont(Font[1]);
    Button.show();

    return MyApp.exec();
}

Вот что получилось:
e885ad1b750c4cf784fdc1182a8725cf.png
Теперь нужно сам алгоритм писать. Но как слоты-сигналы реализовать? Я понял, что через connect, но как не доходит.
Сделать бесконечный цикл? Как я понял, нужно при нажатии кнопки "ВЫЧИСЛИТЬ", подать сигнал в 3 слота: в 2 ComboBox'а и в редактируемый LineEdit. Тогда я получу строку из LineEdit, переведу ее в число, и потом if-else-if'ами вычислю и во второй LineEdit выведу после преобразования в строку.
  • Вопрос задан
  • 1752 просмотра
Подписаться Оценить Комментировать
Решения вопроса 2
@Mercury13
Программист на «си с крестами» и не только
Нет, мы заводим где-то новый слот и подаём сигнал в него.
Есть два способа завести новый слот: либо унаследоваться от QObject или его наследника (удобно унаследовать главную форму), либо воспользоваться лямбда-функцией C++11. Поскольку все наши формы на стеке, проще всего написать лямбду.

connect(&Button, &QPushButton::clicked, 
            &Base, [&]() {
        // тут код
    });


В реальных проектах каждая форма является наследником от QWidget (или чего-то подобного) и хранит свои компоненты. А слоты — это функции в форме.
Ответ написан
EgoRusMarch
@EgoRusMarch Автор вопроса
C++ Developer
Нужно было создавать виджеты нижнего уровня внутри класса виджета верхнего уровня. Версия 2.0:
main
#include <QtWidgets>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication ThisApp(argc,argv);

    Widget ConverterWeights;
    ConverterWeights.show();

    return ThisApp.exec();
}

widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QtWidgets>

class Widget : public QWidget
{
Q_OBJECT

public:
    QLabel      *Title;
    QLineEdit   *Input;
    QLineEdit   *Output;
    QComboBox   *UnitWI;
    QComboBox   *UnitWO;
    QPushButton *Button;

public:
    Widget() : QWidget()
    {
        Title   = new QLabel(this);
        Input   = new QLineEdit(this);
        Output  = new QLineEdit(this);
        UnitWI  = new QComboBox(this);
        UnitWO  = new QComboBox(this);
        Button  = new QPushButton(this);

        ConfigBase();
        ConfigTitle();
        ConfigInput();
        ConfigOutput();
        ConfigUnitWI();
        ConfigUnitWO();
        ConfigButton();

        QObject::connect(Button,SIGNAL(clicked(bool)),this,SLOT(PushButton()));
    }
    ~Widget() {}

private:
    void ConfigBase();
    void ConfigTitle();
    void ConfigInput();
    void ConfigOutput();
    void ConfigUnitWI();
    void ConfigUnitWO();
    void ConfigButton();

public slots:
    void PushButton()
    {
        /*code*/
    }
};

#endif
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Zifix
@Zifix Куратор тега Qt
Barbatum
Что, вам досталась версия учебника совсем без примеров сигналов и слотов? Может все-таки класс хоть создатите, в main.cpp сигналов и слотов нет.

MyApp.exec(); — и есть бесконечный цикл
Ответ написан
devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
Сделайте отдельный класс для окна. Т.е. как-то так:
main.cpp:
#include "mainwindow.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QtWidgets/QMainWindow>
#include <QtWidgets/QPushButton>


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void buttonPressed();
private:
    void setupUi();
    QPushButton *pushButton;
};

#endif // MAINWINDOW_H

mainwindow.cpp:
#include "mainwindow.h"

#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    setupUi();
}

MainWindow::~MainWindow()
{

}

void MainWindow::buttonPressed()
{
    QMessageBox::warning(this, "Hello", "Hello, World");

}

void MainWindow::setupUi()
{
    if (objectName().isEmpty())
        setObjectName(QStringLiteral("MainWindow"));

    resize(400, 300);
    setCentralWidget(new QWidget(this));

    pushButton = new QPushButton(centralWidget());
    pushButton->setObjectName(QStringLiteral("pushButton"));
    pushButton->setGeometry(QRect(90, 90, 92, 27));

    connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(buttonPressed()));

}

*.pro:
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TEMPLATE = app
TARGET = untitled27
INCLUDEPATH += .

HEADERS += mainwindow.h
SOURCES += main.cpp mainwindow.cpp
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы