Qt, Базы данных

Qt. Динамическое создание виджетов на форме

Динамическое создание виджетов на форме может помочь, когда расположение и/или видимость виджетов подпадает под какие-то условия. Приведу пример. Допустим, в базе данных есть некая таблица, в которой хранятся настройки видимости, подписи, id наименований колонок основных таблиц базы, где хранятся важные данные:

CREATE TABLE table_settings
(
id serial NOT NULL,
table_id integer NOT NULL,
column_id integer,
visible boolean NOT NULL DEFAULT true,
caption character varying(50),
name_ character varying(50),
CONSTRAINT table_settings_pkey PRIMARY KEY (id),
CONSTRAINT table_settings_table_id_fkey FOREIGN KEY (table_id)
REFERENCES table_names (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
)

где

  • id — ID записи п/п
  • table_id — id таблицы, о колонках которой хранится информация
  • visible — должна ли быть данная колонка видна
  • caption — название колонки, которое задается пользователем
  • name_ — наименование колонки, которое задается при создании таблицы
CREATE TABLE table_names
(
id serial NOT NULL,
name_ character varying NOT NULL,
CONSTRAINT table_names_pkey PRIMARY KEY (id),
CONSTRAINT table_names_name__key UNIQUE (name_)
)

А это, собственно, та таблица, где хранятся наименования таблиц, для которых нам надо выставить некие настройки.

Для динамического создания виджетов (пусть в нашем примере это будут виджеты классов QLabel и QLineEdit — подпись и поле ввода) на форме разместим объект QGridLayout, куда мы будем «пихать» виджеты. Я еще делаю такой трюк: помещаю в layout объекты в ряд в таком количестве, как хочу видеть результат:

Динамическое создание виджетов на форме в Qt

Далее эти два виджета делаю невидимыми:

ui->label->setVisible(false);
ui->lineEdit->setVisible(false);

Для того, чтобы не просто разместить виджеты на форме, но и потом брать из них информацию для наших нужд, объявим в отделе private класса формы объект класса QVector<QLineEdit*> lineEdits.

Теперь приступим непосредственно к динамическому созданию виджетов.

QSqlQuery query;
//произведем выборку необходимых значений из базы данных
if (!query.exec(QString("select column_id, caption, name_, visible from table_settings "
"where "
"table_id = (select id from table_names where "
"name_ = 'products') "
"order by column_id")))
qDebug() << query.lastError().text(); 
while (query.next()) { 
	QLabel *newLabel = new QLabel(this); //пользовательское наименование колонки newLabel->setText(query.value(1).toString()+":");
	newLabel->setObjectName("label"+query.value(2).toString());
	//видимый в зависимости от значения visible в результатах запроса
	newLabel->setVisible(query.value(3).toBool());
	//размещаем в layout
	ui->widgetsLayout->addWidget(newLabel); //QGridLayout
	QLineEdit *newEdit = new QLineEdit(this);
	newEdit->setObjectName(query.value(2).toString());
	newEdit->setVisible(query.value(3).toBool());
	ui->widgetsLayout->addWidget(newEdit);
	//добавляем в вектор
	lineEdits.push_back(newEdit);
}
//подстройка размера формы в зависимости от расположенных на ней виджетов
this->resize(this->sizeHint());

Динамическое создание виджетов на форме в Qt

Чтобы обратится к отдельному объекту в векторе, достаточно указать его индекс:

for (int i = 0; i < lineEdits.size(); ++i)
	qDebug() << lineEdits[i]->objectName() << " - " << lineEdits[i]->text();

Более элегантная и универсальная версия этого метода представлена здесь: Динамическое создание виджетов Qt. QGridLayout

Qt. Динамическое создание виджетов на форме: 2 комментария

Оставьте своё мнение...

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.