HexSpinBox из примера в книге Бланшет |
Здравствуйте, гость ( Вход | Регистрация )
HexSpinBox из примера в книге Бланшет |
Steklova Olga |
23.12.2011, 16:18
Сообщение
#1
|
Участник Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: 4 |
Здравствуйте!
Мне понадобился в программе виджет для редактирования 16-ного числа с диапазоном [0..FFFFFF]. Использовала для этого QLineEdit. Более-менее работает, но хочется менять значение по стрелочкам, как в QSpinBox.Нашла в книге Ж.Бланшет "Qt4 программирование QUI на C++" в главе 5 пример, где на основе QSpinBox создается класс HexSpinBox. Там установлен диапазон значений, он правильно анализируется при изменении значения по стрелочкам, НО юзер может ввести значение, превышающее диапазон. Как это исправить? Сообщение отредактировал Steklova Olga - 27.12.2011, 10:33 |
|
|
BlueIceScream |
23.12.2011, 22:06
Сообщение
#2
|
Студент Группа: Участник Сообщений: 56 Регистрация: 21.11.2011 Из: Республика Дагестан Пользователь №: 3016 Спасибо сказали: 18 раз(а) Репутация: 3 |
Не совсем понятно что вам нужно. Пользователю позволяется вводить данные, которые поддерживает QRegExpValidator. Если вам нужен диапазон [0..FFFFFF] просто замените:
1) setRange(0x0, 0xFFFFFF); 2) QRegExp ("[0-9A-Fa-f]{1,6}") Стрелочки анализируют состояние членов-данных (minimum, maximum) установленных через setRange. Обычный ввод не контролируется этими членами-данными, после того как вы переопределили функцию validate. Вся ответственность на проверку при вводе ложится на вашу функцию. Если есть необходимость использовать параметры (minimum,maximum), то используйте следующий код:
Если существует тесная связь с функцией validate родителя и хотите использовать именно ее для проверки, то можете использовать следующий код
Именно для вашего случая считаю наилучшим выбор с изменениями setRange и QRegExp описанный в самом начале. Сообщение отредактировал BlueIceScream - 23.12.2011, 22:47 |
|
|
Steklova Olga |
26.12.2011, 10:52
Сообщение
#3
|
Участник Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: 4 |
Спасибо за внимание, BlueIceScream
Заменила в книжном примере функцию validate и указала в конструкторе диапазон значений: При таком-то диапазоне все чудно работает: можно вводить значения и в строке, и менять по стрелкам, в обоих случаях проверяется диапазон.НО, если в setRange указать ненулевое min значение, то программа тут же сломается!!! Что с этим делать? А можно еще сделать так, чтобы юзеру было разрешено в строке вводить 'a'...'f', но они бы сразу отображались в верхнем регистре? А вариант с использованием QLineEdit мне не очень нравится, потому что в этом случае юзер может совсем стереть значение в QLineEdit и мне придется принудительно вписывать туда какое-нибудь значение, например минимальное, и удобных стрелочек там нет, и диапазон там так легко не задашь. |
|
|
BlueIceScream |
26.12.2011, 16:25
Сообщение
#4
|
Студент Группа: Участник Сообщений: 56 Регистрация: 21.11.2011 Из: Республика Дагестан Пользователь №: 3016 Спасибо сказали: 18 раз(а) Репутация: 3 |
Цитата НО, если в setRange указать ненулевое min значение, то программа тут же сломается!!! Что с этим делать? Пожалуйста не используйте setRange в конструкторе. Используйте эту функцию сразу после создания объекта. Как делаете обычно для QSpinBox. Я использовала ее в конструкторе потому что введенное по умолчанию значение через setRange проходит проверку в любом случае. Цитата А можно еще сделать так, чтобы юзеру было разрешено в строке вводить 'a'...'f', но они бы сразу отображались в верхнем регистре? При входе в QValidator::State HexSpinBox::validate(QString &text, int &pos) используйте пожалуйста: text=text.toUpper(); |
|
|
Steklova Olga |
26.12.2011, 18:33
Сообщение
#5
|
Участник Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: 4 |
Получился вот такой код (правда, в таком варианте очень неудобно редактировать число в строке):
main.cpp Раскрывающийся текст
Раскрывающийся текст
Раскрывающийся текст
PS Получается, что в книге Бланшет фраза на стр. 106 ошибочна? ("Теоретически следует возвращать Invalid или Intermediate для значений, лежащих вне диапазона наборного счетчика, но QSpinBox достаточно "умен" и может самостоятельно отследить эту ситуацию.") Сообщение отредактировал Steklova Olga - 27.12.2011, 10:51 |
|
|
BlueIceScream |
26.12.2011, 19:56
Сообщение
#6
|
Студент Группа: Участник Сообщений: 56 Регистрация: 21.11.2011 Из: Республика Дагестан Пользователь №: 3016 Спасибо сказали: 18 раз(а) Репутация: 3 |
Цитата PS Получается, что в книге Бланшет фраза на стр. 106 ошибочна? ("Теоретически следует возвращать Invalid или Intermediate для значений, лежащих вне диапазона наборного счетчика, но QSpinBox достаточно "умен" и может самостоятельно отследить эту ситуацию.") Мариус Бугге, Пол Олав и Жасмин Бланшет ошиблись? А мы нет? Это что то нереальное. Конено же нет. Пример Жасмин работает так как надо. Работает отлично. Ее предложение которое вы привели тоже истина. И ее решение намного лучше, чем которое предложила я. Если вы хорошенько присмотритесь к ее примеру и тому что у вас получилось, сразу станет ясно где хороший код, а где мусор. Итак. В своем примере Жасмин исходит из следующих соображений: 1) Стрелки никогда не выведут значение за диапазон. 2) Пусть пользователь вводит все что угодно, однако после того как элемент потеряет фокус QSpinBox все равно установит реальное значение из диапазона. Например: если вы введете число выходящее за диапазон (а пример Жасмин позволяет это сделать), затем элемент потеряет фокус, и вы увидите что в элементе стоит максимальное значение диапазона. QSpinBox непременно проверит его и поставит верное значение. Но это случится после потери фокуса. Вам же этого не хотелось. Вам хотелось чтобы пользователь просто не мог вводить и все. Теперь посмотрите на ваш пример. Вроде бы все чудесно работает. Однако... Допустим диапазон (10,255). Пользователь хочет ввести значение 0x90. Такое значение допустимо. судя по диапазону. Но что делает элемент при этом? Он не пускает стереть букву A, которое представляет собой минимальное значение диапазона и стирать его функция validate не даст. Почему? Ведь пользователь хочет ввести вполне разрешенное число 0x90. Таким образом получается что первая цифра должна быть больше A. Очень большие сложности при вводе не правда ли? А некоторые разрешенные значения кроме как копировать-вставить или нажатиями на стрелочки и не введешь. Теперь я думаю понятно почему Жасмин не делает проверку при вводе. Она оставляет это все на рассмотрение QSpinBox по завршению ввода. И я думаю это лучший вариант. Таким образом ошибается не Жасмин. А мы. И ошибаемся серьезно. |
|
|
Steklova Olga |
27.12.2011, 12:06
Сообщение
#7
|
Участник Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: 4 |
Наверное, окончательный вариант кода:
main.cpp Раскрывающийся текст
Раскрывающийся текст
Раскрывающийся текст
Цитата Вам же этого не хотелось. Вам хотелось чтобы пользователь просто не мог вводить и все. Мне на самом деле хотелось, чтобы пользователю было max удобно вводить данные, и чтобы программа была написана так, как положено у хороших программистов. А Вы, BlueIceScream, мне очень подробно пояснили этот пример. Благодарю Вас! И еще на тему ввода... В окне диалога задаю значения для нескольких параметров, затем закрываю диалог, нажав одну из кнопок Применить или Отмена. Для некоторых параметров просто выбираю одно значение. А вот для других выбираю диапазон, то есть задаю и min, и max значение. Я позволяю задать min значение больше max значения, а по кнопке Применить в таком случае отображаю эти значения красным цветом, а также вывожу в окне диалога красным цветом надпись "Неверно задан диапазон значений". А как это обычно делают? |
|
|
wiz29 |
27.12.2011, 12:13
Сообщение
#8
|
Старейший участник Группа: Участник Сообщений: 600 Регистрация: 7.7.2010 Из: Санкт-Петербург Пользователь №: 1866 Спасибо сказали: 94 раз(а) Репутация: 12 |
Везде делают по-разному, все зависит от стиля информирования об ошибках в приложении.
Например в Adobe Photoshop появляются диалоги с допустимыми диапазонами по завершению ввода в спин бокс, в котором пользователю сообщается допустимый интервал и введенное значение корректируется к ближайшей границе этого интервала. В других приложениях могут выводится сообщения о недопустимости интервалов в момент нажатия на кнопку применить, все зависит от принятой стратегии в вашем приложении. Ведь можно просто "повесить" валидатор, основываясь на значении в поле ввода "min" или "max" (в зависимости от того куда вводим), не давая возможности пользователю ввести недопустимое значение... |
|
|
Steklova Olga |
27.12.2011, 15:18
Сообщение
#9
|
Участник Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: 4 |
Я, наконец, оценила плюсы созданного класса HexSpinBox.
Вводишь в строке значение < min - автоматически получаешь при потере фокуса равное min. Вводишь в строке значение > max - автоматически получаешь при потере фокуса равное max. У стандартного QSpinBox другой алгоритм. Хорошо, конечно, что нельзя ввести в строке значение > max. Но при вводе значения < min при потере фокуса автоматически устанавливается предыдущее значение. Мне кажется, что логичнее было бы устанавливать при этом min значение. Написала в результате себе класс DecSpinBox, аналогичный HexSpinBox. А стандартный QSpinBox удобен, если min значение = 0. Сообщение отредактировал Steklova Olga - 27.12.2011, 15:22 |
|
|
BlueIceScream |
27.12.2011, 18:10
Сообщение
#10
|
Студент Группа: Участник Сообщений: 56 Регистрация: 21.11.2011 Из: Республика Дагестан Пользователь №: 3016 Спасибо сказали: 18 раз(а) Репутация: 3 |
Если необходима тотальная изоляция неправильных вводимых данных пользователя и известен диапазон, то применяйте если это возможно QSlider. Для него достаточно использование мыши, а пользователи не любят возиться то с мышью, то с клавиатурой для ввода данных. И процесс намного нагляднее.
|
|
|
Текстовая версия | Сейчас: 23.11.2024, 18:33 |