На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
Дорогие девчонки! Поздравляем вас с праздником 8 Марта!
msm.ru
! Правила раздела *nix / gcc / Eclipse / Qt / wxWidgets / GTK+
  • При создании темы ОБЯЗАТЕЛЬНО указывайте версию тулкита / библиотеки / компилятора.
  • Перед тем как задать вопрос, сформулируйте его правильно, чтобы вас могли понять.
  • Нарушение Правил может повлечь наказание со стороны модераторов.


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: Majestio
  
> Работа с QTCreator начинающего
    Здравствуйте!
    Начинаю осваивать QT (Windows, Msys2). Чтобы это делать на конкретном примере, решил перевести на QT свой проект на C# по работе с АЦП. Начал с создания контролов на форме. Возникли следующие вопросы:
    1. При запуске программы при изменении размера формы с помощью правого нижнего угла размер можно сделать гораздо меньше используемого мной tabWidget. Как сделать так, чтобы размеры формы можно было изменить только так, чтобы они не были меньше пространства, занимаемого на форме контролами?
    2. Как у groupBox сделать более толстыми ограничивающие его линии? А то по умолчанию они очень тонкие и их плохо видно.
    3. Я выбрал для формы formLayout. Может опытные пользователи подкажут, какие лайоуты лучше выбирать для формы с многими контролами?
    Проект прикрепил.
    Прикреплённый файлПрикреплённый файлqtCreator.zip (3 Кбайт, скачиваний: 29)
      tumanovalex, как говорится "на вкус и цвет - фломастеры разные" :lol: Попробую тебе выкатить своих личных, считай, аксиом. Все это бережно запомнено на основе собственных проб и ошибок.

      1. Забудь дизайнер QtCreator'а

      Постарайся забыть его очень надежно и не вспоминать. Начинающим кажется, мол вот оно - накликаю "контролов" и сразу стану счастливее в плане экономии времени. Но это не так сто раз. Во первых, чаще не удобно помнить все лайяуты, особенно если есть несколько вложений. Сложно помнить всех их поведения (надо лазить в свойства и выяснять). И наверное самое неприятное - то, что часть того, что должно быть в коде (а именно сами указатели на контролы) спрятаны в UI, вместо наглядной прописки в приватной части класса/классов. Я понимаю, что мой совет скорее всего воспримется сразу в штыки. Мол как-так такой вижуал тулз и в помойку! За всеми этими манипуляциями идет лавинообразное усложнение последующих настроек правильного размещения и поведения. Их же потом нужно будет еще в логику сигналами-слотами обвязывать. Поэтому однозначно - все UI-дизайнерство QtCreator'а нафик!

      2. Свойства виджетов

      У виджетов, в том числе и контролов, кои ими и являются - нет собственных предустановленных размеров. Но у них есть:
      1) Способность сжиматься до пикселя
      2) Способность растягиваться до максимально допустимых размеров, которые позволяет родительский лайяут
      3) Способность корректировать свое поведение политиками размеров и ограничителями.
      Что касается последнего пункта. Запомни два полезных сеттера, которые иногда желательно использовать, иногда - это когда уместно. Часто предустановленное поведение менять не имеет смысла. Речь об этом, пример:

      ExpandedWrap disabled
        lineEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
        lineEdit->setMinimumSize(50,200);

      Это же касается и главного окна программы. Его также можно настроить так, чтобы задать ему минимально допустимые размеры. Тоже касается и максимально допустимых, это тоже есть, если это нужно.

      3. Размещение и настройка геометрии виджетов

      Самый простой способ - программно накидать нужный интерфейс, а потом за пару-тройку итераций подобрать минимально допустимые размеры и задать их также программно. См. методы выше. Есть еще один солюшен, если форма содержит чрезвычайно много настроек, и нет возможности их разнести на табы, или разнести в виде дерева пунктов и панели настроек этих пунктов. Для этого можно в качестве базового виджета использовать скроллируемую область QScrollArea. Но лучше это использовать как "спасательный круг", а не повседневно. При терпении любой интерфейс можно раскидать и упорядочить достаточно наглядно и компактно. Да, иногда можно и попытаться вычислять и настраивать ограничители размеров не статически, а динамически при выполнении программы. Для этого нужно будет уметь получать системные метрики операционной системы и работать с ними (размеры символов шрифтов, размеры скроллов & etc). Но это учат уже в следующем классе ;)

      4. Стилизация

      Во фэймворке Qt используется урезанная версия CSS. По вопросу утолщения обводки groupBox ... Это возможно решить примерно вот так:

      ExpandedWrap disabled
        QGroupBox *groupBox = new QGroupBox("Заголовок");
        groupBox->setStyleSheet("QGroupBox { border: 2px solid gray; }");

      И опять же совет - так не делать. Пользователь этого не ожидает. Он привык к выбранной им теме оформления! Он её желает, а ты его толсто троллишь :lol: Так что, или дать ему настраивать, или не делать такое вообще.

      5. Выбор типов лайяутов

      Тут однозначного ответа нет. Но есть стратегия - Бритва Оккама. Делай как получается проще. А вариантов бывает, как правило, несколько. Запомни, иногда проще использовать в качестве вложенного элемента лайяута - вложенный лайяут со своими элементами, чем громоздить какой-нибудь QGridLayout, а потом пытаться отстроить поведение его отдельных элементов. Уверен, как только ты откажешься от UI-дизайнера и внимательно начитаешься документации по размещениям, этот вопрос уже будет на уровне рефлексов.
        Спасибо за ответ. Самый сложный для меня - пункт 1. Как-то плохо представляю программное размещение элементов без QTCreator. Может быть у Вас есть тестовый проект, в котором это используется? Хотелось бы его поизучать и попытаться разобраться с достоинствами создания интерфейса без QTCreator.
          Цитата tumanovalex @
          Спасибо за ответ. Самый сложный для меня - пункт 1. Как-то плохо представляю программное размещение элементов без QTCreator. Может быть у Вас есть тестовый проект, в котором это используется? Хотелось бы его поизучать и попытаться разобраться с достоинствами создания интерфейса без QTCreator.

          На первых порах можете моделировать формы визуально, а потом из графического редактора переносить координаты в свой проект
            Цитата macomics @
            На первых порах можете моделировать формы визуально, а потом из графического редактора переносить координаты в свой проект

            Очень-очень плохой и неграмотный совет!!! Никаких координат. Только взаимное размещение и политики размеров и ограничений контролов. Qt, исходя из системных метрик текущей операционной системы, сам расставит и растянет управляющие элементы как надо. Если речь не идет о 2D или 3D графике - вообще забыть про какие-то там координаты!!! Максимум что можно указывать в пикселях - это дополнительные отступы. Но и это от лукавого. Программа ДОЛЖНА СООТВЕТСТВОВАТЬ и по цветовой гамме, и по геометрии - выбранной пользователем теме оформления. Либо предлагать свои настройки. Но в виде дополнительных настроек - а не основного костыльно-забитого кода!
              Цитата tumanovalex @
              Может быть у Вас есть тестовый проект, в котором это используется? Хотелось бы его поизучать и попытаться разобраться с достоинствами создания интерфейса без QTCreator.


              Далее я размещу сознательно-кривой проект. На нем можно посмотреть как создаются внешние и вложенные лайяуты и контролы. На нем же имеет смысл поразмыслить, с помощью замены какими типами лайяутов можно улучшить внешний вид.

              Прикреплённая картинка
              Прикреплённая картинка



              TestoLayout.pro
              ExpandedWrap disabled
                greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
                CONFIG += c++17
                SOURCES += \
                    main.cpp \
                    dialog.cpp
                 
                HEADERS += \
                    dialog.h
                 
                # Default rules for deployment.
                qnx: target.path = /tmp/$${TARGET}/bin
                else: unix:!android: target.path = /opt/$${TARGET}/bin
                !isEmpty(target.path): INSTALLS += target


              main.cpp
              ExpandedWrap disabled
                #include "dialog.h"
                 
                #include <QApplication>
                 
                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    Dialog w;
                    w.show();
                    return a.exec();
                }


              dialog.h
              ExpandedWrap disabled
                #ifndef DIALOG_H
                #define DIALOG_H
                 
                #include <QtWidgets>
                 
                // #include <QDialog>   - - - > чтобы не парится, сразу всё ниже заменяем на #include <QtWidgets>
                // #include <QLineEdit> - - - >
                // #include <QCheckBox> - - - >
                // #include <QLabel>    - - - >
                 
                class Dialog : public QDialog
                {
                    Q_OBJECT
                 
                    QLineEdit *firstName;     // явно поля объявляем тут, потом на них будем вешать сигналы-слоты
                    QLineEdit *lastName;      // явно поля объявляем тут, потом на них будем вешать сигналы-слоты
                 
                public:
                    Dialog(QWidget *parent = nullptr);
                    ~Dialog();
                    void SetupWidgets();
                };
                #endif // DIALOG_H


              dialog.cpp
              ExpandedWrap disabled
                #include "dialog.h"
                 
                Dialog::Dialog(QWidget *parent)
                    : QDialog(parent)
                {
                    firstName = new QLineEdit();               // просто инициализируем контрол, хотя можно это сделать и в SetupWidgets
                    lastName = new QLineEdit();                // просто инициализируем контрол, хотя можно это сделать и в SetupWidgets
                 
                    SetupWidgets();                            // инициализация контролов
                 
                    //setMinimumSize(640,480);                 // можно поэксперементировать как-нибудь потом
                }
                 
                Dialog::~Dialog()
                {
                }
                 
                void Dialog::SetupWidgets()
                {
                    QVBoxLayout *L = new QVBoxLayout();         // самый внешний лайяут - см. последнее действие в этом методе!
                 
                    QHBoxLayout *LFirst = new QHBoxLayout();    // лайяут имени (метка+поле ввода)
                    QHBoxLayout *LLast = new QHBoxLayout();     // лайяут фамиллии (метка+поле ввода)
                 
                    LFirst->addWidget(new QLabel("Имя:"));      // добавляем лабел
                    LFirst->addWidget(firstName);               // добавляем поле ввода
                 
                    LLast->addWidget(new QLabel("Фамилия:"));   // добавляем лабел
                    LLast->addWidget(lastName);                 // добавляем поле ввода
                 
                    L->addLayout(LFirst);                       // добавляем лаяут имени в конечный лайяут
                    L->addLayout(LLast);                        // добавляем лаяут фамилии в конечный лайяут
                 
                    setLayout(L);                               // устанавливаем конечный (внешний) лайяут для нашего окна
                }


              Добавлено
              Читаем доку по размещениям и выбираем кандидатов. Подсказка: очевидных на замену внешнему (*L) в данном случае - два. Но один тут чуть-чуть лучше, все же ;) Ваш выбор?

              Добавлено
              Скрытый текст


              Хозяйке на заметку!

              Прикреплённая картинка
              Прикреплённая картинка


              Чтобы память "не текла" ...

              До тех пор пока мы не вызвали addWidget или addLayout для контрола(ов), конторлы, созданные в методах с помощью new так и останутся висеть в памяти (да, и если при инициализации не указывать "родителя")! И их нужно будет удалять вручную. Но если вы вызвали addWidget или addLayout, за этот элемент не беспокойтесь. Когда будет нужно - его удалит "родитель".
                Цитата Majestio @
                Очень-очень плохой и неграмотный совет!!! Никаких координат. Только взаимное размещение и политики размеров и ограничений контролов. Qt, исходя из системных метрик текущей операционной системы, сам расставит и растянет управляющие элементы как надо. Если речь не идет о 2D или 3D графике - вообще забыть про какие-то там координаты!!! Максимум что можно указывать в пикселях - это дополнительные отступы. Но и это от лукавого. Программа ДОЛЖНА СООТВЕТСТВОВАТЬ и по цветовой гамме, и по геометрии - выбранной пользователем теме оформления. Либо предлагать свои настройки. Но в виде дополнительных настроек - а не основного костыльно-забитого кода!

                Вот с таким подходом на Qt интерфейс вечно ездит туда сюда и вылазит за пределы окон. Интерфейс у программы с такими ляпами выглядит куда менее профессиональным, чем если бы он был жестко прибит по координатам. Лучше пускай на координатах тренируется, а уже потом со всем остальным разбирается
                Сообщение отредактировано: macomics -
                  Цитата macomics @
                  Вот с таким подходом на Qt интерфейс вечно ездит туда сюда и вылазит за пределы окон. Интерфейс у программы с такими ляпами выглядит куда менее профессиональным, чем если бы он был жестко прибит по координатам. Лучше пускай на координатах тренируется, а уже потом со всем остальным разбирается

                  Это происходит только тогда, когда автор плохо читал документацию по системе размещений Qt, и не разобрался в её сути. С прямыми руками никаких вышеописанных косяков не происходит. Система размещений Qt сделана грамотно, адаптивна к размерам. Твой совет - это примерно как посоветовать веб-верстальщику не использовать flex или grid, а прибивать div'ы по абсолютным координатам. Так себе совет, сам понимаешь.

                  Позиционирование элементов по конкретным координатам - этот подход является тяжёлым наследием ;) ранних GUI систем, а-ля VCL из CBuilder/Delphi. В Qt это не так работает.
                    Цитата Majestio @
                    Это происходит только тогда, когда автор плохо читал документацию по системе размещений Qt, и не разобрался в её сути. С прямыми руками никаких вышеописанных косяков не происходит.

                    Вот как раз из-за подобных косяков я и отказался от использования Qt приложений. В них постоянно такая шляпа встречалась. Возвращаться к их использованию как-то не тянет больше.
                      Цитата macomics @
                      Вот как раз из-за подобных косяков я и отказался от использования Qt приложений. В них постоянно такая шляпа встречалась. Возвращаться к их использованию как-то не тянет больше.

                      Просто поленился изучить теорию, вот и результат. Вот поэтому я и прошу не "рекламировать" свой неправильный опыт и подход.
                        Цитата Majestio @
                        Просто поленился изучить теорию, вот и результат. Вот поэтому я и прошу не "рекламировать" свой неправильный опыт и подход.

                        Так это не мои приложения. Даже в VLC при переключении на Qt его простейший интерфейс с маленькой кучкой кнопок ведет себя криво.
                        Сообщение отредактировано: macomics -
                          Цитата macomics @
                          Даже в VLC при переключении на Qt его простейший интерфейс с маленькой кучкой кнопок ведет себя криво.

                          Еще раз повторюсь - в Qt и VLC совершенно разные подходы по размещениям контролов. Их нельзя "переключить" просто так. Нужно перепроектировать! Именно из-за твоих попыток "переключить" и происходят косяки! Всё, ладно. Как говорят: "желающий да услышит". Больше повторяться у меня нет желания.
                            Взял за основу Ваш проект. Попробую поработать с элементами из него, а также включить в него свои элементы. Мне потребуется некоторое время, чтобы изучить основы размещения элекментов. Дальнейшие вопросы следует задавать в этой теме или создать новую?
                              Цитата tumanovalex @
                              Взял за основу Ваш проект. Попробую поработать с элементами из него, а также включить в него свои элементы. Мне потребуется некоторое время, чтобы изучить основы размещения элекментов. Дальнейшие вопросы следует задавать в этой теме или создать новую?

                              Я думаю оптимально будет - "один вопрос=одна тема". В плане форума - это вообще must have. Меньше путаницы, больше конкретики.
                                Спасибо за ответ, понятно
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0555 ]   [ 20 queries used ]   [ Generated: 13.03.25, 16:59 GMT ]