пятница, 10 апреля 2009 г.

Таблица параметров постпечатной обработки

На самом деле, у всех вариантов формы "параметры изделия" (предыдущий пост) есть один существенный недостаток: если, к примеру, на предприятии используется некая операция постпечатной обработки, отсутствующая на форме, то пользователь не сможет добавить ее, или, другой пример, если присутствует некая операция, которая не используется на данном предприятии - пользователь не сможет убрать ее с формы.
Есть два решения этой проблемы - потратить много-много лет на тщательное изучение типографского дела, итогом чего станет совершенная форма, на которой будут учтены все возможные полиграфические операции, либо же реализовать форму с возможностью настройки "под себя".

1. Описание
Все параметры изделия можно разделить на два типа - обязательные и возможные. К первым относятся тираж изделия, его формат, красочность и бумага. Прочие параметры - ламинация, биговка, тип скрепления - относятся ко второму типу, которые и требуют пользовательской настройки. Объединим эти параметры в такой таблице...

В первой колонке - название операции. Когда пользователь выбирает определенную операцию (активирует чекбокс), открываются строки с уточняющими параметрами (к примеру, тип, красочность и вид УФ-лака). Общая сводка параметров данной операции отображается во второй колонке в строке с ее названием (первоначально здесь - значение по умолчанию). Для удобства реализовано два режима просмотра таблицы - все строки и строки только отмеченных операций.
Что касается пользовательской настройки - дополнить таблицу новыми операциями, или удалить ненужные, пользователь может отредактировав xml-файл, из которого загружается таблица при старте программы.



2. Реализация
Создать подобную таблицу в Qt можно несколькими способами. К примеру, на основе TableWidget. Вначале, реализуем несколько собственных классов: PostpressTableWidgetItem - наследник от QTableWidgetItem, в который добавим переменную int parent_row, а также PostpressComboBox и PostpressLineEdit, наследующие от QComboBox и QLineEdit и в которые добавим следующие переменные - int parent_row, int pos.
Теперь пишем загрузчик таблицы.

// открываем xml-файл...
// заполняем таблицу
int row = 0; // номер текущей строки
int parent_row = 0; // номер "родительской" строки

while (!child.isNull())
{
// читаем название операции и значение по умолчанию
QString name = child.firstChildElement("name").text();

QString default_value = child.firstChildElement("default_value").text();

// добавляем строку

m_ui->tableWidget_postpress->insertRow(row);

// заполняем первую колонку

PostpressTableWidgetItem *item = new PostpressTableWidgetItem();

item->setText(name);

item->setCheckState(Qt::Unchecked);

item->setParentRow(parent_row);

m_ui->tableWidget_postpress->setItem(row, 0, item);

// заполняем вторую колонку

PostpressTableWidgetItem *item_2 = new PostpressTableWidgetItem();

item_2->setText(default_value);

item_2->setParentRow(parent_row);

m_ui->tableWidget_postpress->setItem(row, 1, item_2);

// читаем параметры данной операции

QDomElement param = child.firstChildElement("param");

while (!param.isNull())

{

// извлекаем название параметра и его возможные значения

QString param_name = param.firstChildElement("name").text();

QString param_value = param.firstChildElement("value").text();

m_ui->tableWidget_postpress->insertRow(++row);

// заполняем колонку с названием параметра

PostpressTableWidgetItem *item_3 = new PostpressTableWidgetItem();

item_3->setText(param_name);

// задаем родительскую строку -

// для строки параметра операции родительской строкой

// будет строка с названием операции

item_3->parent_row = parent_row;

m_ui->tableWidget_postpress->setItem(row, 0, item_3);

// заполняем колонку с возможными значениями параметра

QString temp = param_value;

QStringList param_value_list = temp.split(",");

if (!param_value_list.empty())

{

if (param_value_list.size() > 1)

{

// если у параметра несколько возможных значений

// устанавливаем в колонку комбобокс

PostpressComboBox *cb = new PostpressComboBox (parent_row, row - parent_row - 1);

cb->insertItems(0, param_value_list);

connect(cb, SIGNAL(currentIndexChanged(QString)), this, SLOT(UpdatePostpressComboBox(QString)));

m_ui->tableWidget_postpress->setCellWidget(row, 1, cb);

}

else

{

// если возможных значений одно

// устанавливаем в колонку лайнэдит

PostpressLineEdit *cb = new PostpressLineEdit (parent_row, row - parent_row - 1);

cb->setText(param_value_list[0]);

connect(cb, SIGNAL(textChanged(QString)), this, SLOT(UpdatePostpressLineEdit(QString)));

m_ui->tableWidget_postpress->setCellWidget(row, 1, cb);

}

}

// прячем строку параметра операции

m_ui->tableWidget_postpress->hideRow(row);

param = param.nextSiblingElement("param");

}

++row;

parent_row = row;

child = child.nextSiblingElement("operation");

} // завершение цикла while (!child.isNull())


Что касается слотов - см. исходники.