
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.141.24.119] |
![]() |
|
![]() |
|
|
Здравствуйте!
Начинаю осваивать QT (Windows, Msys2). Чтобы это делать на конкретном примере, решил перевести на QT свой проект на C# по работе с АЦП. Начал с создания контролов на форме. Возникли следующие вопросы: 1. При запуске программы при изменении размера формы с помощью правого нижнего угла размер можно сделать гораздо меньше используемого мной tabWidget. Как сделать так, чтобы размеры формы можно было изменить только так, чтобы они не были меньше пространства, занимаемого на форме контролами? 2. Как у groupBox сделать более толстыми ограничивающие его линии? А то по умолчанию они очень тонкие и их плохо видно. 3. Я выбрал для формы formLayout. Может опытные пользователи подкажут, какие лайоуты лучше выбирать для формы с многими контролами? Проект прикрепил. Прикреплённый файл ![]() |
Сообщ.
#2
,
|
|
|
tumanovalex, как говорится "на вкус и цвет - фломастеры разные"
![]() 1. Забудь дизайнер QtCreator'а Постарайся забыть его очень надежно и не вспоминать. Начинающим кажется, мол вот оно - накликаю "контролов" и сразу стану счастливее в плане экономии времени. Но это не так сто раз. Во первых, чаще не удобно помнить все лайяуты, особенно если есть несколько вложений. Сложно помнить всех их поведения (надо лазить в свойства и выяснять). И наверное самое неприятное - то, что часть того, что должно быть в коде (а именно сами указатели на контролы) спрятаны в UI, вместо наглядной прописки в приватной части класса/классов. Я понимаю, что мой совет скорее всего воспримется сразу в штыки. Мол как-так такой вижуал тулз и в помойку! За всеми этими манипуляциями идет лавинообразное усложнение последующих настроек правильного размещения и поведения. Их же потом нужно будет еще в логику сигналами-слотами обвязывать. Поэтому однозначно - все UI-дизайнерство QtCreator'а нафик! 2. Свойства виджетов У виджетов, в том числе и контролов, кои ими и являются - нет собственных предустановленных размеров. Но у них есть: 1) Способность сжиматься до пикселя 2) Способность растягиваться до максимально допустимых размеров, которые позволяет родительский лайяут 3) Способность корректировать свое поведение политиками размеров и ограничителями. Что касается последнего пункта. Запомни два полезных сеттера, которые иногда желательно использовать, иногда - это когда уместно. Часто предустановленное поведение менять не имеет смысла. Речь об этом, пример: ![]() ![]() lineEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); lineEdit->setMinimumSize(50,200); Это же касается и главного окна программы. Его также можно настроить так, чтобы задать ему минимально допустимые размеры. Тоже касается и максимально допустимых, это тоже есть, если это нужно. 3. Размещение и настройка геометрии виджетов Самый простой способ - программно накидать нужный интерфейс, а потом за пару-тройку итераций подобрать минимально допустимые размеры и задать их также программно. См. методы выше. Есть еще один солюшен, если форма содержит чрезвычайно много настроек, и нет возможности их разнести на табы, или разнести в виде дерева пунктов и панели настроек этих пунктов. Для этого можно в качестве базового виджета использовать скроллируемую область QScrollArea. Но лучше это использовать как "спасательный круг", а не повседневно. При терпении любой интерфейс можно раскидать и упорядочить достаточно наглядно и компактно. Да, иногда можно и попытаться вычислять и настраивать ограничители размеров не статически, а динамически при выполнении программы. Для этого нужно будет уметь получать системные метрики операционной системы и работать с ними (размеры символов шрифтов, размеры скроллов & etc). Но это учат уже в следующем классе ![]() 4. Стилизация Во фэймворке Qt используется урезанная версия CSS. По вопросу утолщения обводки groupBox ... Это возможно решить примерно вот так: ![]() ![]() QGroupBox *groupBox = new QGroupBox("Заголовок"); groupBox->setStyleSheet("QGroupBox { border: 2px solid gray; }"); И опять же совет - так не делать. Пользователь этого не ожидает. Он привык к выбранной им теме оформления! Он её желает, а ты его толсто троллишь ![]() 5. Выбор типов лайяутов Тут однозначного ответа нет. Но есть стратегия - Бритва Оккама. Делай как получается проще. А вариантов бывает, как правило, несколько. Запомни, иногда проще использовать в качестве вложенного элемента лайяута - вложенный лайяут со своими элементами, чем громоздить какой-нибудь QGridLayout, а потом пытаться отстроить поведение его отдельных элементов. Уверен, как только ты откажешься от UI-дизайнера и внимательно начитаешься документации по размещениям, этот вопрос уже будет на уровне рефлексов. |
Сообщ.
#3
,
|
|
|
Спасибо за ответ. Самый сложный для меня - пункт 1. Как-то плохо представляю программное размещение элементов без QTCreator. Может быть у Вас есть тестовый проект, в котором это используется? Хотелось бы его поизучать и попытаться разобраться с достоинствами создания интерфейса без QTCreator.
|
Сообщ.
#4
,
|
|
|
Цитата tumanovalex @ Спасибо за ответ. Самый сложный для меня - пункт 1. Как-то плохо представляю программное размещение элементов без QTCreator. Может быть у Вас есть тестовый проект, в котором это используется? Хотелось бы его поизучать и попытаться разобраться с достоинствами создания интерфейса без QTCreator. На первых порах можете моделировать формы визуально, а потом из графического редактора переносить координаты в свой проект |
Сообщ.
#5
,
|
|
|
Цитата macomics @ На первых порах можете моделировать формы визуально, а потом из графического редактора переносить координаты в свой проект Очень-очень плохой и неграмотный совет!!! Никаких координат. Только взаимное размещение и политики размеров и ограничений контролов. Qt, исходя из системных метрик текущей операционной системы, сам расставит и растянет управляющие элементы как надо. Если речь не идет о 2D или 3D графике - вообще забыть про какие-то там координаты!!! Максимум что можно указывать в пикселях - это дополнительные отступы. Но и это от лукавого. Программа ДОЛЖНА СООТВЕТСТВОВАТЬ и по цветовой гамме, и по геометрии - выбранной пользователем теме оформления. Либо предлагать свои настройки. Но в виде дополнительных настроек - а не основного костыльно-забитого кода! |
Сообщ.
#6
,
|
|
|
Цитата tumanovalex @ Может быть у Вас есть тестовый проект, в котором это используется? Хотелось бы его поизучать и попытаться разобраться с достоинствами создания интерфейса без QTCreator. Далее я размещу сознательно-кривой проект. На нем можно посмотреть как создаются внешние и вложенные лайяуты и контролы. На нем же имеет смысл поразмыслить, с помощью замены какими типами лайяутов можно улучшить внешний вид. Прикреплённая картинка
TestoLayout.pro ![]() ![]() 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 ![]() ![]() #include "dialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); } dialog.h ![]() ![]() #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 ![]() ![]() #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, за этот элемент не беспокойтесь. Когда будет нужно - его удалит "родитель". |
Сообщ.
#7
,
|
|
|
Цитата Majestio @ Очень-очень плохой и неграмотный совет!!! Никаких координат. Только взаимное размещение и политики размеров и ограничений контролов. Qt, исходя из системных метрик текущей операционной системы, сам расставит и растянет управляющие элементы как надо. Если речь не идет о 2D или 3D графике - вообще забыть про какие-то там координаты!!! Максимум что можно указывать в пикселях - это дополнительные отступы. Но и это от лукавого. Программа ДОЛЖНА СООТВЕТСТВОВАТЬ и по цветовой гамме, и по геометрии - выбранной пользователем теме оформления. Либо предлагать свои настройки. Но в виде дополнительных настроек - а не основного костыльно-забитого кода! Вот с таким подходом на Qt интерфейс вечно ездит туда сюда и вылазит за пределы окон. Интерфейс у программы с такими ляпами выглядит куда менее профессиональным, чем если бы он был жестко прибит по координатам. Лучше пускай на координатах тренируется, а уже потом со всем остальным разбирается |
Сообщ.
#8
,
|
|
|
Цитата macomics @ Вот с таким подходом на Qt интерфейс вечно ездит туда сюда и вылазит за пределы окон. Интерфейс у программы с такими ляпами выглядит куда менее профессиональным, чем если бы он был жестко прибит по координатам. Лучше пускай на координатах тренируется, а уже потом со всем остальным разбирается Это происходит только тогда, когда автор плохо читал документацию по системе размещений Qt, и не разобрался в её сути. С прямыми руками никаких вышеописанных косяков не происходит. Система размещений Qt сделана грамотно, адаптивна к размерам. Твой совет - это примерно как посоветовать веб-верстальщику не использовать flex или grid, а прибивать div'ы по абсолютным координатам. Так себе совет, сам понимаешь. Позиционирование элементов по конкретным координатам - этот подход является тяжёлым наследием ![]() |
Сообщ.
#9
,
|
|
|
Цитата Majestio @ Это происходит только тогда, когда автор плохо читал документацию по системе размещений Qt, и не разобрался в её сути. С прямыми руками никаких вышеописанных косяков не происходит. Вот как раз из-за подобных косяков я и отказался от использования Qt приложений. В них постоянно такая шляпа встречалась. Возвращаться к их использованию как-то не тянет больше. |
Сообщ.
#10
,
|
|
|
Цитата macomics @ Вот как раз из-за подобных косяков я и отказался от использования Qt приложений. В них постоянно такая шляпа встречалась. Возвращаться к их использованию как-то не тянет больше. Просто поленился изучить теорию, вот и результат. Вот поэтому я и прошу не "рекламировать" свой неправильный опыт и подход. |
Сообщ.
#11
,
|
|
|
Цитата Majestio @ Просто поленился изучить теорию, вот и результат. Вот поэтому я и прошу не "рекламировать" свой неправильный опыт и подход. Так это не мои приложения. Даже в VLC при переключении на Qt его простейший интерфейс с маленькой кучкой кнопок ведет себя криво. |
Сообщ.
#12
,
|
|
|
Цитата macomics @ Даже в VLC при переключении на Qt его простейший интерфейс с маленькой кучкой кнопок ведет себя криво. Еще раз повторюсь - в Qt и VLC совершенно разные подходы по размещениям контролов. Их нельзя "переключить" просто так. Нужно перепроектировать! Именно из-за твоих попыток "переключить" и происходят косяки! Всё, ладно. Как говорят: "желающий да услышит". Больше повторяться у меня нет желания. |
Сообщ.
#13
,
|
|
|
Взял за основу Ваш проект. Попробую поработать с элементами из него, а также включить в него свои элементы. Мне потребуется некоторое время, чтобы изучить основы размещения элекментов. Дальнейшие вопросы следует задавать в этой теме или создать новую?
|
Сообщ.
#14
,
|
|
|
Цитата tumanovalex @ Взял за основу Ваш проект. Попробую поработать с элементами из него, а также включить в него свои элементы. Мне потребуется некоторое время, чтобы изучить основы размещения элекментов. Дальнейшие вопросы следует задавать в этой теме или создать новую? Я думаю оптимально будет - "один вопрос=одна тема". В плане форума - это вообще must have. Меньше путаницы, больше конкретики. |
Сообщ.
#15
,
|
|
|
Спасибо за ответ, понятно
|