Как выровнять 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. О том что такое модели и зачем они нужны, вы можете прочитать в этой статье .
Обновлено 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 подхватывает текущую тему окружения, и комбобокс выглядит везде по-разному.