инициализация контроллов (wx c++ vs2017

Это русская секция форума wxWidjets. В этой секции вы можете обсуждать любые вопросы, связанные с wxWidgets на вашем родном языке.
genx74
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sat Feb 11, 2023 6:14 am

Re: инициализация контроллов (wx c++ vs2017

Post by genx74 »

Yes Yes Yes. Thank you very much for your help and patience! You answered me before I had time to ask)) I just had an idea to take the font size as the basis for scaling. Which the user can change in the settings, or which is automatically calculated based on the screen resolution when the program starts. I just wanted to ask "whether the best element size is taken based on its content?".

I'm just studying sequentially the book "Julian Smart and Kevin Hock
with Stefan Csomor". And there I saw that you can create elements and at the end of the constructor apply something like "set size based on content". And the content is created with the "best size" based on the given font size. And I already saw that in wx it is very convenient to work with the font.You can even ignore the OS Windos style set by the user, but simply extract this font, increase its size, and install it.This will be the initial size of the window with the correct height and width, and not, as I indicated, just visually by eye (200, 400) and all elements shrink to this size at random and not according to the "best size" rule.In the coming days I will experiment.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 6737
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: инициализация контроллов (wx c++ vs2017

Post by ONEEYEMAN »

Hi,
In order to do an automatic HighDPI scaling, you have to have a Manifest with HighDPIAware setting.
Otherwise , you are correct.

Thank you.
genx74
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sat Feb 11, 2023 6:14 am

Re: инициализация контроллов (wx c++ vs2017

Post by genx74 »

Hello.
I figured out the sizers, while everything turns out, it works, it scales depending on the font. wxwidget has an enumerator and 7 font sizes, which is enough.
I can't figure out the veto() function. I have a spinbutton and a button with an image. On the spinup spindown event, certain settings are loaded into the dialog box, incl. button card. The settings are taken from the vector containing the structures. The user can select an image with a click button, then press the spinbutton to go to the next page. But if the picture is not selected - button bitmap = wxNULLbitmap then you need to disable the spinup spindown event. I looked at an example using veto(). But it is applied inside the event, i.e. when the spinvalue has already changed.

spinvalue is used to get the element of the vector. those. vector[spinvalue]. Therefore, if an event occurs when it should not be, the numbering is lost. You can probably roll back the setvalue (getvalue -1) value in this case, or do bind-unbind, connect-disconnect, but I think it would be more correct to use veto on the spinbutton, but not in the spinup spindown event itself, but somewhere in the picture selection event. If at button.click the picture is not selected, it remains empty, then disable the spinup spindown event. Could you please advise, because all the examples only consider veto on close in the close or quit event itself.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 6737
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: инициализация контроллов (wx c++ vs2017

Post by ONEEYEMAN »

Hi,
In this case you need to disable the control, so the user will not be able to change the spin value.
Or depending on the application design/needs, hide/show the spin control.

Thank you.
genx74
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sat Feb 11, 2023 6:14 am

Re: инициализация контроллов (wx c++ vs2017

Post by genx74 »

Well, yes, that's what I'm trying to do with event.veto() However, I access this event inside the event when the spinvalue change has already happened. How to use veto for spinup event from another event like button click?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 6737
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: инициализация контроллов (wx c++ vs2017

Post by ONEEYEMAN »

Hi,
Can you describe in English or Russian the flow control of the program you are doing?

What I suggested is to call spinctrl->Disable() so that user will not be able to do anything with the control.

Thank you
genx74
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sat Feb 11, 2023 6:14 am

Re: инициализация контроллов (wx c++ vs2017

Post by genx74 »

Спасибо за помощь. Я попробую использовать disable(). Я все еще пишу прототип программы, чтобы изучить wxwidget и найти нужные мне методы и свойства и научиться их использовать. Грубо говоря, часть программы, над которой я сейчас работаю, выглядит так:

Есть wxPanel, в ней есть несколько wxCtrlText, wxButton с картинкой и spinbutton. Есть структура, в которой хранятся значения wxCtrlText и путь к картинке. Есть вектор этих структур. С помощью wxButton.click() вызывается диалоговое окно выбора изображения. Если - ок, картинка устанавливается как bitmap для wxButton. Пользователь может заполнить wxCtrlText данными и нажать spinup. В этом случае данные из элементов управления копируются в структуру, а структура добавляется в вектор vector.push_back(mystruct). Если пользователь нажимает кнопку Spindown, то загружаются данные из предыдущей структуры, сохраненной в векторе. В этом случае, какой элемент вектора необходимо загрузить, определяется значением spinvalue.

Я думал, какой признак должен определять, заполнены данные или нет, и я думал, что если нет картинки, то нет и данных. Таким образом, если пользователь нажал кнопку, но выбрал «отменить», растровое изображение на кнопке устанавливается в wxNULLbitmap; refresh(); кнопка пуста. И тогда при нажатии spinup значение спина не должно меняться, иначе значение не будет совпадать с порядковым номером элемента в векторе.

Если картинка выбрана и пользователь нажимает spinup, то данные сохраняются в vector[spinvalue] затем, если spinvalue < vector.size (то есть в векторе есть следующий элемент), то данные и картинка сохраняются в вектор vector[spinvalue]. Если spinvalue = vector.size (текущий элемент вектора — последний), то текущие данные также сохраняются и в вектор добавляется новая структура. Чтобы избежать пустых структур в векторе, пользователь не может перемещаться вперед или назад, если изображение не выбрано. Только если текущие данные являются последним элементом вектора, когда spindown и картинки нет, считается, что пользователь передумал добавлять новую запись, поэтому в этом случае обратный переход разрешен и vector.pop_back(spinvalue) выполняется, тое удаляется последний элемент вектора.

Это немного похоже на работу такого элемента как Tab с winapi, но в VBA такого элемента не было, поэтому реализация этой части программы была такой, как я описал. Только там обработка данных была не в самих событиях spinup spindown, а в этих событиях проверялось изображение и только потом вызывалась соответствующие функции передачи данных.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 6737
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: инициализация контроллов (wx c++ vs2017

Post by ONEEYEMAN »

Доброго времени суток,
Я понял.
Самое простое решение - вызвать Disable() для спина и вызывать Enable() только если есть картинка.
Кстати, нажатие на саму кнопку - не лучшее решение.
Попробуйте справа от кнопки положить wxFilePicker.

Как-то так.

Спасибо.
genx74
Earned a small fee
Earned a small fee
Posts: 12
Joined: Sat Feb 11, 2023 6:14 am

Re: инициализация контроллов (wx c++ vs2017

Post by genx74 »

Спасибо.
Да, disable() это хорошее решение проблемы

Да, click надо будет переделать, потому что файловый диалог загружается относительно долго, во время этого сохраняется нажатое состояние кнопки, поэтому изображение пропадает потом появляется через пару секунд. Это некрасиво и неправильно, единственное почему я использую кнопку для изображения, потому что не знал как прикрутить событие click() к staticbitmap. Недавно я увидел в примере как это сделать и хочу попробовать.
Отдельную кнопку не хотелось бы добавлять для выбора файла из экономии места. Ну и както вроде логично, кликнул картинку и сразу выбрал, тем более в диалоге сразу можно и папку по умолчанию нужную прописать и фильтр форматов настроить.
К сожалению в учебниках описаны только основные виджеты. И вот разные полезные виджеты иногда попадаются в комментариях на форумах, когда часть кода где их можно было бы использовать уже написана.

И еще пока одну проблему не могу победить. В классе wxPanel прописаны все контролы и в конце конструктора вызывается загрузка первой картинки. Т.е. при создании этого диалога, по умолчанию загружается какой то шаблон\образец данных. Размер картинки не устанавливается, потому что объект только создается и не имеет наверное еще свойств size (я так думаю). В процессе работы когда окно показано, то для загружаемой картинки делается rescale под размер кнопки в которую она загружается. А вот в самом конструкторе класса это не работает. Хотя в конструкторе в конце стоит layout() и только потом загрузка первой картинки.
wxPanel создается по нажатию меню в mainframe. я думал в mainframe после создания объекта wxPanel вызвать функцию устанавливающую первые данные по умолчанию, и тогда картинка бы правильно была rescale потому что окно есть и показано в нужном масштабе. Однако в mainframe мне не виден метод wxPanel.setfirstdata(); хотя он в классе wxPanel как public.

И в wxwidget странно реализован метод show, т.е. я могу только enable\disable элементы в зависимости нужны они при текущих настройках или не нужны. Если же я пытаюсь использовать show\hide то они не уничтожаются но из сайзеров исчезают и все расположение контролов сбивается. непонятно почему ведь кнопки\объекты не уничтожаются а просто становятся show(false)
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 6737
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: инициализация контроллов (wx c++ vs2017

Post by ONEEYEMAN »

Доброго времени суток,
genx74 wrote: Sun Mar 19, 2023 5:41 pm Спасибо.
Да, disable() это хорошее решение проблемы

Да, click надо будет переделать, потому что файловый диалог загружается относительно долго, во время этого сохраняется нажатое состояние кнопки, поэтому изображение пропадает потом появляется через пару секунд. Это некрасиво и неправильно, единственное почему я использую кнопку для изображения, потому что не знал как прикрутить событие click() к staticbitmap. Недавно я увидел в примере как это сделать и хочу попробовать.
Отдельную кнопку не хотелось бы добавлять для выбора файла из экономии места. Ну и както вроде логично, кликнул картинку и сразу выбрал, тем более в диалоге сразу можно и папку по умолчанию нужную прописать и фильтр форматов настроить.
wxFilePicker даст Вам возможность выбрать файл и сделать все о чем Вы здесь написали. Вам не нужно изобретать велосипед и писать диалог самому.
И еще - это как файл выбипается . В 99% всех приложений используется FilePicker. Пользователь просто булет смотреть и не понимать что ему делать.
genx74 wrote: Sun Mar 19, 2023 5:41 pm К сожалению в учебниках описаны только основные виджеты. И вот разные полезные виджеты иногда попадаются в комментариях на форумах, когда часть кода где их можно было бы использовать уже написана.

И еще пока одну проблему не могу победить. В классе wxPanel прописаны все контролы и в конце конструктора вызывается загрузка первой картинки. Т.е. при создании этого диалога, по умолчанию загружается какой то шаблон\образец данных. Размер картинки не устанавливается, потому что объект только создается и не имеет наверное еще свойств size (я так думаю). В процессе работы когда окно показано, то для загружаемой картинки делается rescale под размер кнопки в которую она загружается. А вот в самом конструкторе класса это не работает. Хотя в конструкторе в конце стоит layout() и только потом загрузка первой картинки.
wxPanel создается по нажатию меню в mainframe. я думал в mainframe после создания объекта wxPanel вызвать функцию устанавливающую первые данные по умолчанию, и тогда картинка бы правильно была rescale потому что окно есть и показано в нужном масштабе. Однако в mainframe мне не виден метод wxPanel.setfirstdata(); хотя он в классе wxPanel как public.
Можно посмотреть на код и скрееншот?
genx74 wrote: Sun Mar 19, 2023 5:41 pm И в wxwidget странно реализован метод show, т.е. я могу только enable\disable элементы в зависимости нужны они при текущих настройках или не нужны. Если же я пытаюсь использовать show\hide то они не уничтожаются но из сайзеров исчезают и все расположение контролов сбивается. непонятно почему ведь кнопки\объекты не уничтожаются а просто становятся show(false)
There is a solution for that - use wxRESERVE_SPACE_EVEN_IF_HIDDEN when adding the control to the sizer.

Thank you.
Post Reply