Создать таблицу в эксель в qt в графическом
Давайте немного расскажу вам о работе с таким элементом как TableWidget.
Если дважды щёлкнуть мышью по размещенной на форме таблице, то появится окно, которое позволяет создавать столбцы, строки и даже наполнение таблицы.
- Чтобы установить количество столбцов и строк из кода программы, необходимо сделать следующее:
- Чтобы удалить столбец или строку необходимо вызвать соответствующие функции:
- У таблицы есть горизонтальный и вертикальный заголовки.
- Чтобы изменить заголовок, необходимо сделать следующее:
- Заголовки можно скрыть в окне свойств визуального редактора
Работа с элементом QTableWidget
- Каждая ячейка в таблице QTableWidget для того чтобы что-то отобразить, должна содержать в себе элемент QTableWidgetItem.
- Объект QTableWidgetItem должен создаваться в динамической области памяти с помощью ключевого слова new.
- Данный элемент может содержать в себе иконку.
- Создавать этот объект можно как заранее, так и непосредственно при добавлении значения в ячейку таблицы.
- Для добавления значения в ту или иную ячейку в таблице используется функция setItem() у элемента QTableWidget.
- Функция setItem() принимает следующие параметры: индекс строки, индекс столбца, экземпляр объекта QTableWidgetItem.
Но конструктор вызывается уже без создания иконки.
Обратите внимание, что объект создаётся в динамической области памяти при помощи ключевого слова new, но удалять такой объект (delete) не нужно!
Так как указатель на этот объект мы передаем таблице, сама таблица берёт бразды правления в свои руки.
Т.е. она сама поймёт, когда необходимо освободить память от этих объектов и произвести все необходимые манипуляции для предотвращения утечек памяти.
Так же обратите внимание, что попытка создать экземпляр объекта в ячейке индексов которой не существует в таблице - будет проигнорирована.
Например, установили в таблице количество строк равное 10, а количество столбцов равное 3.
При попытке вызвать следующую команду:
Использование QTableWidget будет первым способом, который посоветуют Вам для создания таблиц с чекбоксами на Qt. Поэтому давайте рассмотрим и этот вариант работы с таблицами в Qt и конечно же применим чекбоксы.
Итак, чтобы урок был более приближен к реальности, захватим немного программного кода из урока по QDataWidgetMapper . А именно возьмём класс для работы с базой данных, чтобы уж сразу делать таблицу из базы данных. После чего сделаем форму главного окна приложения и выведем данные из таблицы с отображением чекбоксов. Естественно, при включении приложения таблица база данных будет создана и заполнена несколькими записями, которые мы и будем выводить в виджет.
Программный код был написан в QtCreator 3.3.1 на основе Qt 5.4.1.
- 1. Структура проекта для QTableWidget
- 2. mainwindow.ui
- 3. mainwindow.h
- 4. mainwindow.cpp
- 5. database.h
- 6. database.cpp
- 7. Итог
Структура проекта для QTableWidget
Предлагаю ознакомиться со структурой проекта:
- QTableWidgetExample.pro - профайл;
- mainwindow.h - заголовочный файл основного окна приложения;
- mainwindow.cpp - исходный код окна;
- main.cpp - основной исходный файл, с которого стартует приложение;
- mainwindow.ui - формочка основного окна приложения;
- database.h - заголовочный файл вспомогательного класса, применяющегося для работы с информацией, которая помещена в базу данных;
- database.cpp - исходный файл вспомогательного класса, применяющегося для работы с информацией, которая помещена в базу данных;
mainwindow.ui
Всё, что Вам нужно сделать с этим файлом, это кинуть в форму главного окна в дизайнере QTableWidget.
mainwindow.h
В данном файле объявляется объект базы данных, с которым мы будем работать, а также метод для заполнения данными QTableWidget.
mainwindow.cpp
В этом файле заключена цель всего урока, а именно настройка QTableWidget и заполнение его записями из базы данных.
database.h
Данный файл отличается от того, что был взят из урока по QDataWidgetMapper тем, что была добавлена define директива для чекбокса, соответственно это повлекло изменение методов в файле database.cpp . А именно insertIntoDeviceTable и createDeviceTable .
database.cpp
В результате при запуске программы будет создано приложение, в котором будет таблица с четырьмя записями, две из которых будут с отмеченными чекбоксами.
Итак, начнем с теории. В Qt существует абстрактный класс QStyle, ответственный, как не сложно догадаться, за стилизацию приложения. От него унаследовано некоторое количество классов (QWindowStyle, QMacStyle и т.д.), которые представляют собой стили, эмулирующие стандартный внешний вид операционной системы. Мы будем делать свой стиль для приложения по их образу и подобию. Qt требует, чтобы пользовательские стили были унаследованы не напрямую от QStyle, а от одного из его классов-наследников. Документация рекомендует выбрать наиболее близкий к желаемому системный стиль, и изменить его «под себя». Мы же будем наследовать наш класс от не менее абстрактного, чем QStyle, класса QCommonStyle.
Как же происходит рисование элементов внутри стиля? Класс QStyle имеет набор функций, названия которых начинаются со слова draw:
- drawComplexControl()
- drawControl()
- drawItemPixmap()
- drawItemText()
- drawPrimitive()
Каждая из них делает свою небольшую часть работы по отрисовке элементов.
drawComplexControl() используется для рисования составных виджетов, то есть таких, которые содержат в самих себе несколько других виджетов.
В качестве примера можно привести QSpinBox, который, как несложно догадаться, реализует обычный SpinBox и состоит из поля ввода и двух маленьких кнопок:
drawControl() рисует стандартные виджеты вроде кнопок и полей ввода.
drawPrimitive() рисует так называемые примитивные элементы, например, рамки.
drawItemPixmap() и drawItemText() имеют вполне говорящие названия и делают именно то, что вы могли бы от них ожидать. Детальные описание всех функций, а также их аргументов, можно очень легко найти в документации Qt, поэтому я на этом останавливаться не буду.
В нашем примере, мы будем делать стиль для элемента QTableWidget, который представляет собой обыкновенную таблицу. Стили для остальных элементов делаются абсолютно аналогично.
Начинаем
Первым делом, создадим новый класс С++. При создании класса, Qt услужливо предлагает нам написать его название, а так же название класса, от которого мы хотим наследовать. Назовем его для простоты myStyle, и укажем наследование от QCommonStyle. После этого, Qt создаст нам пару файлов (.h и .cpp), в которых, для начала, мы хотим получить примерно такую заготовку:
Наша функция main() будет выглядеть следующим образом:
Как видите, все что мы делаем — это устанавливаем наш стиль, создаем виджет и отображаем его. На данном этапе у нас есть только пустой стиль, унаследованный от QCommonStyle, поэтому наша таблица будет выглядеть… ну, скажем, не очень привлекательно:
Рассмотрим подробнее из чего состоит таблица.
Структура, в общем, довольно простая и понятная. Стоит разве что остановиться на секунду на заголовках. В Qt разделяют два вида заголовков: горизонтальный (тот, который сверху), и вертикальный (тот, который слева). Под «Областью заголовка» я подразумеваю всю область, на которой впоследствии будет отображен заголовок. Секция — это каждая конкретная ячейка заголовка. Незанятая область — это та часть заголовка, на которой секций нет (это случается, когда суммарный размер всех секций меньше размера таблицы).
Итак, вооружившись этими знаниями, можно стилизовать каждый элемент. Начнем с добавления в наш класс функций
Начнем с функции drawControl(). Добавим в реализацию код:
Ключевой атрибут этой функции — это element, который указывает на тип того, что мы будем рисовать. Внутри switch'a мы будем добавлять по case'у для каждого из тех элементов, которые мы будем рисовать сами. Все остальные будут обрабатываться в default-секции с помощью аналогичной функции родительского класса.
Начнем с рамки, которая окружает нашу таблицу целиком. Я буду делать градиентную рамку. Верхняя и нижняя границы будут белыми, а вертикальные границы будут нарисованы градиентом: они будут белыми по краям и светло-серыми в середине.
Для этого добавим в функцию drawControl() следующий код:
Итак, что же здесь происходит. Сначала мы создаем линейный градиент, направленный сверху вниз. Затем мы задаем цвета для ключевых точек, которых у нас три: начало, конец и середина. Как я уже говорил, начало и конец мы делаем белыми, а середину чуть сероватой.
После этого мы создаем перо и устанавливаем в него наш градиент. Перо в Qt рисует с помощью кисти (QBrush), в роли которой будет выступать градиент. Наконец, функцией drawRect() мы рисуем нашу рамку.
Теперь приступим к заголовкам. Саму область заголовка (CE_Header) нам обрабатывать не нужно. Мы займемся секциями и пустой областью. С пустой областью все очень просто, мы закрасим ее однотонным серым цветом:
С секциями же придется несколько сложнее. Как мы знаем, если на заголовок таблицы нажать, то выделится либо вся строка, либо весь столбец (в зависимости от того, куда мы нажали). При этом заголовок поменяет свой внешний вид, чтобы пользователь видел изменение его состояния. Обычно заголовок либо «вдавливается», либо подкрашивается. Мы хотим сохранить эту функциональность. Более того, хотелось бы, чтобы при выделении ячейки или ячеек, соответствующие заголовки также окрашивались.
Итак, добавим следующий код:
Итак, секция может быть в двух состояниях: активном и неактивном. Для того, чтобы определить это, мы проверяем ее флаги. Флаг State_Sunken показывает, что секция нажата, а флаг State_On показывает, что выбрана ячейка, принадлежащая столбцу (или строке) этой секции. Если хотя бы один из них установлен, мы закрашиваем секцию ровным оранжевым цветом, а также рисуем для нее целиковую границу для того, чтобы оранжевая секция не смотрелась грубо на фоне других (не выделенных) светло-серых частей заголовка.
Если секция неактивна, мы закрашиваем ее градиентом от белого до светло-серого цвета и рисуем границу. Я решил рисовать только вертикальные границы секций, поэтому все что мне нужно — это изобразить вертикальную полоску справа от каждой секции. Чтобы полоски не смотрелись грубо, мы нарисуем их градиентом почти так же, как и рамку всей таблицы: концы полосок будут более светлыми, а середина — более темной. Для этого мы перенастраиваем градиент и устанавливаем его в перо, которым будет рисоваться полоса.
На данном этапе мы получили довольно симпатичный заголовок. Однако при выделении наши ячейки по-прежнему закрашиваются довольно некрасивым цветом по умолчанию. К тому же, стандартная фокусная рамка тоже выглядит не слишком красиво.
За отрисовку ячеек отвечает атрибут CE_ItemViewItem. Добавим в него следующий код:
Здесь нам пришлось сделать гораздо больше. Во-первых, за раскраску выделенных ячеек другим цветом отвечает элемент PE_PanelItemViewItem, который рисуется в функции drawPrimitive(). Поэтому мы должны вызвать эту функцию, передав туда имеющиеся у нас параметры. После этого мы преобразовываем указатель на опции с базового класса QStyleOption в нужный нам класс QStyleOptionViewItemV4. Это нужно, помимо прочего, для получения текста и области рисования этого текста.
Если ячейка, которую мы рисуем, является выделенной то мы рисуем небольшую серую рамку вокруг всей ячейки.
После этого мы получаем размер области, на которой должен бын выведен текст, и делаем небольшой отступ, чтобы текст не появился вплотную к левому верхнему краю. Наконец, мы рисуем текст функцией drawText().
Поскольку при обработки ячеек мы вызываем функцию drawPrimitive для элемента PE_PanelItemViewItem, реализуем отрисовку этого элмента, чтобы выделенные ячейки раскрашивались в какой-нибудь более приятный цвет.
По аналогии с drawControl(), добавим в drawPrimitive() точно такой же switch, и сразу реализуем нужную нам подсветку ячеек:
Наконец, изменим шрифт, которым будет выводиться текст. Добавим в функцию drawItemText() следующий код:
Итак, мы преобразили невзрачную табличку, и теперь она выглядит так:
что на мой взгляд гораздо лучше того, что было изначально.
Преимущества данного подхода
Конечно, создавать стили для всего приложения таким образом — весьма трудоемкая задача. Стиль для одного элемента (как в этой статье) можно сделать очень быстро, но если вы хотите позаботится о всех виджетах (например если вы хотите распространять свой стиль, чтобы другие люди могли им воспользоваться), это может отнять достаточно много времени. Описание элементов, которые должны быть нарисованы для каждого отдельно взятого виджета, я, к примеру, не нашел, и мне пришлось определять их методом «научного тыка». Однако у стилизации таким образом есть ряд существенных преимуществ.
Во-первых, эти стили применяются ко всем элементам. Если у вас есть 300таблиц, то вам не нужно настраивать каждую вручную, стиль к приложению применяется в одну строку.
Во-вторых, стили, созданные таким образом, удобно менять. Это, пожалуй, лучший способ предоставить пользователю возможность изменить стиль приложения через настройки. К тому же, вы можете быть точно уверены, что созданный вами стиль будет каждый раз выглядеть одинаково.
есть какие то table view & table widget но это не то. вобщем как в qtdesigner сделать таблицу, чтобы работать с ней через ui?
хочу сделать обычную таблицу несколько столбцов и какое то количество строк (меняется по ходу работы)
как в qtdesigner сделать таблицу, чтобы работать с ней через ui
зачем Вам это надо?
И чем не устроили QTableView и QTableWidget если не сектрет? Ведь других подобных виджетов в стандартной поставке нет и непредвидится.
других подобных виджетов в стандартной поставке нет и не предвидится.
вообще-то от них можно унаследоваться и переопределить их как хочется и заюзать в изменённом варианте
Я ж говорю про -> стандартную <- поставку.
Я ж говорю про -> ничего не надо <- делать.
в такой постановке соглашусь
как я понял он хочет виджет, который можно заполнить значениями в процессе редактирования формы во время design time, прямо в ui
это можно попробовать сделать, не через анус, но всё же. непонятно только вот напуркуа это нужно
мьсье сильно испорчен дельфями, сам такой был. читай про model<->view в QTableView. в кутях принцииально не получиться показать таблицу в в IDE
дельфями никогда не пользовался, как было сказано выше испорчен сишарпами). вопрос решен пишу руками
я бы делал так:
1) делаете стандартный model/view
2) для модели делаете возможность загрузки данных в каком-нибудь csv (ручками довольно несложно сделать)
3) таблицу забиваете в openoffice.calc, меняете каждый раз что надо в ней и экспортите в csv
4) При загрузке формы подгружаете нужный csv
Топикстартер либо толстенный троль, либо криворукий неуч, которого надо научить читать мануалы.
Читайте также: