ТЗ
21 декабря 2018 г. 6:29

Как выстравивать логику приложения в QTCreator?

Qt

Добрый день, разбираюсь с QT и хочу написать маленькую приложуху и просто уперся в один вопрос: как переключаться между виджетами, как выстраивать архитектуру приложения? Самое понятное для меня, что смог найти в книгах и интернетах это такой вариант: создаем главный виджет, в котором будем переключать существующие mainwid.cpp, потом я создал два пробных виджетам, между которыми хочу переключаться first.cpp и second.cpp. В главной функции создаю экземпляр главного виджета, первого и второго; добавляю первый и второй виджет внутрь стэка виджетов и записываю в переменные номера в стеках каждого и по наступлению события переключаемся между ними. Вопросы: на сколько такая логика имеет место быть? Как обращаться к mainwid, стоит ли создать какой-то слот или что-то еще, я не очень понимаю что нужно прописывать в команде connect третий и четвертый параметры, точнее как обращаться к тому, что должно стоять на месте третьего параметра?
P.S. я даже не могу проверить то, что написал ибо сначала мне компилятор говорил, что all: no such file or directory и останавливался на компиляции файла first.o, а после добавления к проекту файлов second.h и second.cpp выдает ошибку в 13 строке файла main.cpp что он якобы не знает тип second, но все же подключено по аналогии с first, а там нет ошибок, я подавлен....
P.P.S. очень сильно надеюсь на вашу помощь, а то уже совсем всё плывет(((
код:

*.pro

  1. SOURCES += \
  2. main.cpp \
  3. mainwid.cpp \
  4. first.cpp \
  5. second.cpp
  6.  
  7. QT += widgets \
  8. gui
  9.  
  10. HEADERS += \
  11. mainwid.h \
  12. first.h \
  13. second.h

first.h

  1. #ifndef FIRST_H
  2. #define FIRST_H
  3. #include<QApplication>
  4. #include<QtWidgets>
  5.  
  6. class first : public QWidget
  7. {
  8. Q_OBJECT
  9. public:
  10. first();
  11. private:
  12. QPushButton *Button1;
  13. QLabel *label1;
  14. QLabel *label2;
  15. };
  16.  
  17. #endif // FIRST_H

second.h

  1. #ifndef FIRST_H
  2. #define FIRST_H
  3. #include<QApplication>
  4. #include<QtWidgets>
  5.  
  6. class second : public QWidget
  7. {
  8. Q_OBJECT
  9. public:
  10. second();
  11. private:
  12. QPushButton *Button1;
  13. QLabel *label1;
  14. QLabel *label2;
  15. };
  16.  
  17. #endif // FIRST_H

mainwid.h

  1. #ifndef MAINWID_H
  2. #define MAINWID_H
  3. #include<QApplication>
  4. #include<QtWidgets>
  5. #include<QStackedWidget>
  6. #include"first.h"
  7.  
  8. class mainwid : public QWidget
  9. {
  10. Q_OBJECT
  11. public:
  12. mainwid(QWidget* parent = 0);
  13. QStackedWidget *QSW;
  14. private:
  15. };
  16.  
  17. #endif // MAINWID_H

first.cpp

  1. #include"first.h"
  2.  
  3. first::first():QWidget()
  4. {
  5. Button1 = new QPushButton("Back", this);
  6. label1 = new QLabel("1st window", this);
  7. label2 = new QLabel("still window 1", this);
  8. connect(Button1, SIGNAL(clicked()), this, SLOT(setCurrentWindow(int)));
  9. }

main.cpp

  1. #include <QApplication>
  2. #include "mainwid.h"
  3. #include "first.h"
  4. #include "second.h"
  5.  
  6. int main(int argc, char *argv[])
  7. {
  8. QApplication app(argc, argv);
  9. mainwid *Widget = new mainwid();
  10. first *First = new first();
  11. second *Second = new second();
  12. int a = Widget->QSW->addWidget(First);
  13. int b = Widget->QSW->addWidget(Second);
  14. Widget->QSW->setCurrentIndex(a);
  15. Widget->show();
  16. return app.exec();
  17. }

mainwid.cpp

  1. #include"mainwid.h"
  2.  
  3. mainwid::mainwid(QWidget *parent) : QWidget(parent)
  4. {
  5. QSW = new QStackedWidget(this);
  6. }

second.cpp

  1. #include"second.h"
  2.  
  3. second::second():QWidget()
  4. {
  5. Button1 = new QPushButton("Back", this);
  6. label1 = new QLabel("2nd window", this);
  7. label2 = new QLabel("again 2nd window", this);
  8. connect(Button1, SIGNAL(clicked()), this, SLOT(setCurrentWindow(int)));
  9. }
3

Вам это нравится? Поделитесь в социальных сетях!

6
nayk1982
  • 21 декабря 2018 г. 8:33

Добрый день. Советую для начала изучить статьи и разобраться с сигналами и слотами. Это одна из важнейших составляющих программирования с использованием Qt. На данном сайте все изложено довольно понятно и с примерами.
По поводу вопроса о том, что не видно second: у вас в обоих заголовочных файлах

  1. #ifndef FIRST_H
  2. #define FIRST_H
  3. ...

это защита и она сработала ))

    ТЗ
    • 21 декабря 2018 г. 19:02

    да, спасибо) это помогло и вернуло к старой проблеме:

    1. gcc first.o all -o first
    2. gcc: error: all: No such file or directory
    3. <builtin>: recipe for target 'first' failed
    4. make: *** [first] Error 1
    5. 17:54:17: Процесс «/usr/bin/make» завершился с кодом 2.
    6. Ошибка при сборке/установке проекта todoList1 (комплект: Desktop Qt 5.12.0 GCC 64bit)
    7. Во время выполнения этапа «Сборка»

    даже проект новый пересобрал, всё равно не понимаю чего ему не хватает с этим файлом.
    Ну и если абстрагироваться в вопросе про сигналы и слоты, то логика построения приложения сильно неправильная?

      Evgenii Legotckoi
      • 22 декабря 2018 г. 3:35

      Добрый день!

      Помогло... а что именно вы сделали?

      И новый проект пересобрали... но это не значит, что снова был выполнен шаг qmake , лучше просто удалить полностью build каталог.

      Приложение слишком маленькое, чтобы говорить о какой-то архитектуре.
      Косяков в общем-то хватает, начиная от использования устаревшего синтаксиса сигналов и слотов и заканчивая просто вырвиглазным код-стайлом, который в продакшене не используется. Что именно хотите услышать?

        ТЗ
        • 22 декабря 2018 г. 19:43
        • (ред.)

        Я имел в виду, что это надо было исправить:

        1. #ifndef FIRST_H
        2. #define FIRST_H

        qmake всегда запускаю первым делом. Ну, почти всегда.
        Услышать хотел бы как написать приложение, на основе которого можно было бы уже делать что-то большее. Суть в том, что есть у нас две формы и перерисовывать их, сменяя одну другой, в том же окне, а не создавать новое для каждой, здесь я откровенно не могу разобраться.

          Evgenii Legotckoi
          • 22 декабря 2018 г. 19:52

          Это нужно было переписать на

          1. #ifndef SECOND_H
          2. #define SECOND_H

          Ок. Тогда к вопросу о приложении. Если хотите относительно комфортно вести разработку, то я бы рекомендовал всё-таки использовать Qt Designer и накидывать формы в дизайнере, а то если честно, очень потом тяжело разгребать нагромождение только одних формирований формочек, которые могу достигать нескольких тысяч строк кода. Использование дизайнера на самом деле удобная вещь.

          Что касается приложения, то если у вас есть приложение с одним главным окном, то добавлять все виджеты и прочее лучше уже внутри конструктора или методов данного окна приложения, а не так, как у вас сделано в main функции.

          Если у вас в главном окне приложения будут дополнительные диалоги, то можно использовать пул диалогов, если предполагается кеширование, если вам нужно менять виджеты без их пересоздания, а просто переключать, то можете использовать QStackedWidget или QTabView.

          А так, ну, делаете главное окно приложения, диалоги разработываете в отдельно, по возможности с минимальной связью с главным окном, чтобы можно было просто аргументы какие-то передавать им для инициализации и т.д. Тоже самое со сложными виджетами. Но не увлекайтесь преждевременными оптимизациями, если не требуется сложный виджет, или виджет, который будет повторяться в других местах, то его можно накидать прямо в форме главного окна приложения.

          P/S/ и всё-таки откажитесь от записи сигналов и слотов на макросах. Это себя уже отжило, да и порой создаёт больше проблем, чем новый синтаксис на указателях.

            ТЗ
            • 22 декабря 2018 г. 22:57

            Спасибо, буду разбираться

              Комментарии

              Только авторизованные пользователи могут публиковать комментарии.
              Пожалуйста, авторизуйтесь или зарегистрируйтесь