Как выровнять qcombobox
Перейти к содержимому

Как выровнять qcombobox

Как выровнять qcombobox

Группа: Новичок
Сообщений: 4
Регистрация: 31.7.2011
Пользователь №: 2775

Репутация: 0

опции профиля:

Просмотр профиля

Группа: Участник
Сообщений: 297
Регистрация: 23.6.2011
Пользователь №: 2765

Репутация: 3

Переопределить paintEvent или поставить стиль типа такого:

X — это сколько вы хотите отступить от левого края (примерно равно comboBox->width()/2 — длина надписи в пикселях/2)
y — это сколько вы хотите отступить сверху (примерное равно comboBox->height() — сколько вы хотите отступить снизу)

QComboBox — Работа с моделями в Qt5 для отображения данных в виджетах. Часть 1

QComboBox - Работа с моделями в Qt5 для отображения данных в виджетах. Часть 1

Сегодня мы рассмотрим создание простой модели для виджета QComboBox. О том что такое модели и зачем они нужны, вы можете прочитать в этой статье .

Обновлено 07.12.2020. В связи с выходом статьи , посвященной моделям, убрано вступление, оставлена только практическая часть!

Создание нового проекта

Создадим новый пустой проект Qt Widgets Application с главной формой, на форму добавим QComboBox.

Так же добавим на форму кнопку QPushButton и назовем её Add

Запустим проект, чтобы убедиться в отсутствии ошибок.

Теперь нам нужно заполнить нашу модель данными:

В метод MainWindow::MainWindow добавим после ui->setupUi(this); следующий код:

Добавим в mainwindow.h в раздел private строки

Добавим в модель метод для заполнения нашего ComboBox данными.

Добавим в конец MainWindow::MainWindow код

Запустим проект и у нас ComboBox заполнится данными:

Запустим, откроем список и нажмем на кнопку и ничего не происходит!

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

Обратите внимание на метод populate:

Для того, чтобы уведомить модель о том, что у нас появились новые строки данных, мы используем методы beginInsertRows и endInsertRows.

Метод beginInsertRows вызывается перед добавлением новых строк данных, а метод endInsertRows после окончания добавления этих данных.

beginInsertRows принимает три параметра, в первый мы просто передаем QModelIndex(), второй и третий параметры соответственно индексы первого элемента и индекс последнего элемента.

Так как метод populate предназначен для полного обновления списка, мы вызываем метод с параметром 1 и максимальным размером списка.

Обратите внимание, использование beginInsertRows и endInsertRows обязательно!

Рассмотрим наш случай. Если закомментировать эти два метода, то сразу после запуска если вы будете нажимать кнопку, то в ComboBox будет добавлено нужное количество элементов, а если вы сначала откроете список, чтобы проверить количество элементов и нажмете кнопку, то новые строки будут добавлены в список values, но ComboxBox не будет обновлён!

Добавление строки в QComboBox

Но обновлять весь список, когда мы добавляем только один элемент неправильно, давайте добавим отдельный метод для добавления только одной строки в наш ComboBox.

В данном методе мы вычисляем индекс добавляемого элемента и затем, используя beginInsertRows и endInsertRows, добавляем данные в наш QList, таким образом уведомляя модель, о том, что у нас изменились данные.

Изменим слот для кнопки Add

Теперь строки добавляются корректно.

Изменение строки в QComboBox

Давайте теперь попробуем внести изменения в строки нашего QComboBox.

Добавим новую кнопку и назовем ее Edit

Добавим для нее слот:

Запустим, при нажатии на кнопку ничего не происходит. На самом деле происходит изменение названия текущей строки, но она обновится после того, как вы наведете курсор мыши на QComboBox:

Давайте рассмотрим его подробнее:

Просто изменяет строковое значение текущего элемента QComboBox.

Обратите внимание на запись:

Вам необходимо использовать подобное разыменование указателя C++ и квадратные скобки.

У класса QList есть метод at() , позволяющий получить элемент списка по его индексу, но в нашем случае, нам он не подходит. Почему? Давайте рассмотрим его определение:

Обратите на const , это слово означает, вкратце, что данные, которые возвращает объект, нельзя изменить никаким образом, компилятор просто выдаст ошибку. Таким образом нам остается только оператор [] , который избавлен от этого ограничения:

Таким образом единственный способ изменить элемент списка QList – это использовать разыменование (*this->values)[]

Давайте так же рассмотрим индексацию элементов QComboBox.

Индексация элементов в QComboBox

Все элементы в QComboBox индексируются с 0. Следует различать индексы строк QComboBox и индексы значений строк.

Например, при запуске следующий код

Т.е. значения полей класса QPair.

Если же мы добавим строку:

Т.е. именно значение, которое мы поставили в соответствие к строке Select item.

Когда модель оперирует индексами строк и столбцов она оперирует внутренними индексами, которые не имеют никакого отношения к тем значениям, что мы задаем, это важно помнить!

Вернемся к разбору метода on_pushButton_2_clicked()

Первая получает объект класса QModelIndex для текущей строки.

Метод currentIndex принимает два параметра – первый строка, второй – столбец.

Так как у нас в QComboBox всего один столбец, второй параметр мы всегда устанавливаем в 0 .

Метод ui->comboBox->currentIndex() возвращает индекс текущего элемента QComboBox , так что мы передаем его в первом параметре.

Самая важная строчка здесь это

Для того, чтобы уведомить модель, что данные у нас изменились, мы отправляем нашей модели сигнал dataChanged .

Данный сигнал принимает два параметра – оба должны являться экземплярами класса QModelIndex , первый параметр — это строка, а второй это столбец.

Здесь мы указываем два раза полученный нами ранее индекс idx , так как обновляется только один элемент.

Таким же образом мы можем обновить и любой элемент с любым индексом, для примера обновим элемент ComboBox с индексом 4:

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

Давайте добавим в нашу модель метод, который позволит нам, в одну строчку, обновлять данные:

И изменим слот для кнопки Edit

QList::removeAt(): Index out of range.

Я сомневаюсь, что вам потребуется удалять все строки из ComboBox подобным образом, но, если и возникнет такая необходимость, не забудьте проверять количество строк, которое осталось, перед удалением и соответственно обрабатывать возникшую ошибку, в данной статье мы этого делать не будем.

Вставка строк в нужную позицию в QComboBox

Возможно, вам понадобится вставить в QComboBox строку в определённую позицию.

Добавим на форму кнопку AddTo и создадим для нее слот:

Для вставки строки в заданную позицию мы используем метод insert, первым параметром мы передаем индекс, перед которым мы хотим вставить элемент, вторым параметром данные вставляемой строки.

Давайте добавим в нашу модель метод для реализации этого функционала:

Изменим слот для кнопки

Обратите внимание, что при добавлении в позицию не изменяется текущий элемент:

Как сделать нормальный QCombobox?

Как сделать чтобы комбобокс в Qt был нормально выглядящим. Пока удалось сделать только треугольник:

Ты о чем вообще? Что значит «чтобы было как везде»? Где это, «везде» и какой образ для тебя «привычный»?

Вообще говоря, Qt подхватывает текущую тему окружения, и комбобокс выглядит везде по-разному.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *