понедельник, 17 ноября 2008 г.
четверг, 6 ноября 2008 г.
Система калькуляции заказов
Приступили к работе над калькулятором. На данный момент остановились на следующей системе - расчет на основе данных по оборудованию + скидки/наценки по конкретным клиентам. Ниже - пример расчета, основанный на оборудовании. Критика - приветствуется )
Операция
Время переналадки
Скорость
Учетная стоимость/час
Учетный материал 1
Кол-во на приладку
Расход на единицу
Техотходы %
...
Исполнитель
Учетная ставка
Время переналадки
Скорость
Учетная стоимость/час
Учетный материал 1
Кол-во на приладку
Расход на единицу
Техотходы %
...
Исполнитель
Учетная ставка
/
ПРИМЕР
Фальцовка автоматическая
Приладка 15 минут
Скорость 5000/час
Стоимость 1500/час
Техотходы 5%
Оператор фальцаппарта 100р./час
Печать SM-74-4
Переналадка 30 минут
Скорость 10000/час
Стоимость 10000р./час
Бумага на приладку 250 листов
Техотходы 5%.
Печатник 250р./час
Вывод форм Suprasetter
Скорость 12/час
Стоимость 1000 р./час
Формы 300р./шт
Оператор 200р./час
Техотходы 2%
ПРИМЕР
Фальцовка автоматическая
Приладка 15 минут
Скорость 5000/час
Стоимость 1500/час
Техотходы 5%
Оператор фальцаппарта 100р./час
Печать SM-74-4
Переналадка 30 минут
Скорость 10000/час
Стоимость 10000р./час
Бумага на приладку 250 листов
Техотходы 5%.
Печатник 250р./час
Вывод форм Suprasetter
Скорость 12/час
Стоимость 1000 р./час
Формы 300р./шт
Оператор 200р./час
Техотходы 2%
/
ПРИМЕР
Заказ газета А2 4+4 1 фальц 10000 экз.
Калькуляция
Вывод форм тираж 8 шт.
Время операции 1 час.
Стоимость
Формы 2400
Техотходы 50
Оператор 200
Работа оборудования 1000
Итого 3650 р.
Печать SM74-4 Выходной тираж 10100 экз.
2 переналадки
20200 оттисков
Бумага на приладку 500 л
Бумага на техотходы 1000 л.
Всего бумаги 21700 л. * 1,5 р. = 32250 р.
Время печати 3 часа
Стоимость операции 63000 р.
Фальцовка Выходной тираж 10050 экз.
Время операции 2,5 часа
Техотходы 50 экз.
Стоимость 4000 р.
ПРИМЕР
Заказ газета А2 4+4 1 фальц 10000 экз.
Калькуляция
Вывод форм тираж 8 шт.
Время операции 1 час.
Стоимость
Формы 2400
Техотходы 50
Оператор 200
Работа оборудования 1000
Итого 3650 р.
Печать SM74-4 Выходной тираж 10100 экз.
2 переналадки
20200 оттисков
Бумага на приладку 500 л
Бумага на техотходы 1000 л.
Всего бумаги 21700 л. * 1,5 р. = 32250 р.
Время печати 3 часа
Стоимость операции 63000 р.
Фальцовка Выходной тираж 10050 экз.
Время операции 2,5 часа
Техотходы 50 экз.
Стоимость 4000 р.
воскресенье, 28 сентября 2008 г.
Реализация раздела "Заказчики". Часть 3
3. "Корзина"
Таблица "корзина" реализуется аналогично таблице "все заказчики", с единственным отличием - в условии фильтрации proxyModel:
proxyModel->setFilterRegExp(QRegExp("0", Qt::CaseInsensitive, QRegExp::FixedString));
proxyModel->setFilterKeyColumn(10);
- после чего в таблице "корзина" будут отображаться записи, в которых значение колонки "active" равно "0". Таким образом, все что нужно сделать для того, чтобы переместить запись заказчика в корзину - изменить значение "active":
customerform *page = (customerform*) ui.tabWidget->currentWidget(); // получаем указатель на текущую закладку в tabWidget заказчиков
QSqlRecord record = model->record(page->mapper->currentIndex()); // получаем из модели запись текущего заказчика
record.setValue("active", "0"); // устанавливаем active в ноль
model->setRecord(page->mapper->currentIndex(), record); // обновляем запись текущего заказчика
model->submitAll();
ui.tabWidget->removeTab(ui.tabWidget->currentIndex()); // удаляем текущую вкладку
Востановим запись из корзины:
QModelIndex index = ui.tableView->currentIndex(); // индекс выделенной строки в таблице "корзина"
QModelIndex index2 = proxyModel->mapToSource(index); // переводим его из proxyModel в индекс исходной модели
model->setData(cust_model->index(index2.row(), 9), "1"); // изменяем active
model->submitAll();
Удаляем запись навсегда:
QModelIndex index = ui.tableView->currentIndex(); // индекс выделенной строки в таблице "корзина"
QModelIndex index2 = proxyModel->mapToSource(index); // переводим в индекс исходной модели
model->removeRow(index2.row()); // удаляем строку из модели
model->submitAll(); // обновляем базу данных
пятница, 26 сентября 2008 г.
Драйвера в Qt
В стандартной сборке Qt часть драйверов различных модулей внедрены как плагины и при компиляции проекта не включаются в исполняемый файл. Это касается и драйвера SQLite. Т.е. при запуске приложения в системе, где бибилиотека Qt не установлена, нас ждут ошибки, или сообщение - "драйвер не найден". Чтобы решить эту проблему, мы должны либо добавить необходимый драйвер (в случае с SQLite - это qsqlite4.dll, которую надо поместить в директорию sqldrivers в папке с exe-файлом), либо пересобрать Qt, задав с помощью configure включение драйвера непосредственно в библиотеку Qt (для SQLite - это "-qt-sql-sqlite").
вторник, 23 сентября 2008 г.
Реализация раздела "Заказчики". Часть 2
2. Форма для добавления и редактирования данных по заказчикам.
Связать модель с такими виджетами, как TableView или ListView - легко и просто, достаточно только вызвать setModel() и проблема решена. Но как быть, если виджет представляет из себя форму, на которой размещены комбобоксы, лайнедиты и т.п.? Как установить связь менжду этими элементами и SQL-данными?
Реализовать подобное можно двумя способами: 1) не используя QDataWidgetMapper и 2) используя QDataWidgetMapper. Далее - описание второго способа.
Итак, есть виджет, на котором размещены несколько lineEdit. Каждый из них нам нужно связать с той или иной колонкой из таблицы "customers":
lineEdit - название заказчика, lineEdit_1 - город заказчика, ну и т.д.
QDataWidgetMapper *mapper = new QDataWidgetMapper(this); // создаем в конструкторе виджета маппер
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); // определяем стратегию обновления данных
mapper->setModel(model); // назначаем модель с таблицей "customers"
Используя метод addMapping(), установим связь между lineEdit и колонками таблицы:
mapper->addMapping(ui.lineEdit, 0); // имя заказчика
mapper->addMapping(ui.lineEdit_1, 1); // город
mapper->addMapping(ui.lineEdit_2, 2); // улица
mapper->addMapping(ui.lineEdit_3, 3); // офисный телефон
mapper->addMapping(ui.lineEdit_4, 4); // факс
mapper->addMapping(ui.lineEdit_5, 5); // имя контактного лица
mapper->addMapping(ui.lineEdit_6, 7); // мобильный номер
mapper->addMapping(ui.lineEdit_7, 8); // майл
mapper->addMapping(ui.textEdit, 9); // примечание
После того, как мы связали лайнедиты с табличными колонками, осталось только назначить мапперу табличный индекс. Продемонстрируем это на примере открытия записи заказчика из таблицы "Все заказчики" - метод OpenCustomer(QModelIndex), назначенный в качестве слота сигналу doubleClicked виджета tableView:
connect(ui.tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OpenCustomer(QModelIndex)));
После двойного клика на строке виджета tableView в метод OpenCustomer передается текущий индекс из модели, которая была задана виджету. Остается только передать этот индекс маппер, но... В маппер в качестве модели мы назначили QSqlTableModel, а виджету tableView - QSortFilterProxyModel. Чтобы избежать ошибки, необходимо перевести индекс из QSortFilterProxyModel в индекс QSqlTableModel:
QModelIndex index2 = proxyModel->mapToSource(index); // переводим текущий index из QSortFilterProxyModel в QSqlTableModel
mapper->setCurrentModelIndex(index2); // назначаем индекс мапперу
Теперь в лайнедитах отображаются данные из строки, выделенной в виджете tableView. Выше мы выбрали "ручную" стратегию сохранения, таким образом, для того, чтобы изменения в лайнедитах вступили в силу - необходимо вызвать метод submit().
понедельник, 22 сентября 2008 г.
Реализация раздела "Заказчики". Часть 1
Задачи:
1. Стартовая страница с таблицей "Все заказчики", в которой отображаются записи из таблицы "customers" со значением "active" == 1.
2. Форма для добавления и редактирования данных по заказчикам.
3. "Корзина" с таблицей удаленных заказчиков, где отображаются записи со значением "active" == 0.
Реализация:
1. Таблица "Все заказчики".
Вся информация по заказчикам хранится в базе данных "customers.s3db", в таблице "customers". Для отображения записей воспользуемся модулем QSqlTableModel, реализующим технологию модель/вид между SQL-таблицами и такими виджетами, как QListView, QTableView и QTreeView.
QSqlTableModel *model = new QSqlTableModel;
model->setTable("customers");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
setEditStrategy() определяет метод обновления данных в sql-таблице после их изменения в виджете:
QSqlTableModel::OnFieldChange - данные обновляются немедленно;
QSqlTableModel::OnRowChange - новые данные передаются в таблицу после того, как пользователь выделяет другую строку;
QSqlTableModel::OnManualSubmit - изменения вносятся в момент вызова метода submitAll().
Назначим созданную модель виджету QTableView -
tableView->setModel(model);
- после чего виджет tableView будет отображать все строки и колонки из таблицы "customers".
Скрыть некоторые колонки можно как на уровне модели (model->removeColumn(1)), так и на уровне виджета (tableView->hideColumn(1)). Мы воспользуемся вторым методом, и спрячем часть колонок, оставив только название заказчика, имя контактного лица, телефон и емайл.
tableView->hideColumn(1); // прячем название города
tableView->hideColumn(2); // прячем название улицы и т.д.
Колонка "active" в таблице "customers" отображает текущее состояние записи о заказчике: если запись удалениа - "active" принимает значение 0, и запись перемещается в таблицу "Корзина", с возможностью восстановления, или окончательного удаления; если значение "active" == 1, то запись отображается в таблице "Все заказчики".
Есть несколько способов реализации фильтрации строк. Опять же на уровне модели (model->setFilter("active = 1")), или с помощью модуля QSortFilterProxyModel, позволяющим установить правила для фильтрации и сортировки данных между моделью и видом.
Зададим фильтрацию по значению "active" для таблицы "Все заказчики", используя QSortFilterProxyModel:
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model); // указываем в качестве исходной модели QSqlTableModel с таблицей "customers".
proxyModel->setFilterRegExp(QRegExp("1", Qt::CaseInsensitive, QRegExp::FixedString)); // "верное" значение фильтрации
proxyModel->setFilterKeyColumn(10); // задаем номер колонки, по которой будет происходить фильтрация
После того, как правило фильтрации установленно, назначаем proxyModel виджету:
tableView->setModel(proxyModel);
В итоге код для таблицы "Все заказчики" будет выглядеть вот так:
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model);
proxyModel->setFilterRegExp(QRegExp("1", Qt::CaseInsensitive, QRegExp::FixedString));
proxyModel->setFilterKeyColumn(10);
ui.tableView->setModel(proxyModel);
ui.tableView->hideColumn(1);
ui.tableView->hideColumn(2);
ui.tableView->hideColumn(3);
ui.tableView->hideColumn(4);
ui.tableView->hideColumn(9);
ui.tableView->hideColumn(10);
среда, 17 сентября 2008 г.
QTextCodec(Кодировка)
Дело в том, что в Qt по умолчанию стоит отображение, как символов, так и строк в кодировке Unicode - Utf-8, Utf-16. И это правильно, но скажем если вы работаете под операционной системой Windows то там по умолчанию стоит кодировка cp1251 для России! Т.е. кириллица Windows-code page 1251 .
Создали простой проект на Qt :
…………….
#include "testa1.h"
#include "QtGui"
#include "QApplication"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel *label = new QLabel("Здорого эт Юникод", 0);
label->show();
return app.exec();
}
…..
И отобразится что-то вроде -- Çäîðîãî ýò Þíèêîä;
Для нормального отображения нужно сделать следующее, в Qt есть специальный класс QTextCodec проще говоря нам нужно установить в нашем проекте другую кодировку, для этого воспользуемся функцией setCodec();
QTextCodec* codec = QTextCodec::codecForName("CP1251");//создаем указатель на QTextCodex и говорим что его кодировка "cp1251"
QTextCodec::setCodecForCStrings(codec);//устанавливаем для строк CString кодировку cp1251
……………………………………
#include "testa1.h"
#include "QtGui"
#include "QApplication"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextCodec* codec = QTextCodec::codecForName("CP1251");
QTextCodec::setCodecForCStrings(codec);
QTextCodec* codec = QTextCodec::codecForName("CP1251");//создаем указатель на QTextCodex и говорим что его кодировка "cp1251"
QTextCodec::setCodecForCStrings(codec);//устанавливаем для строк CString кодировку cp1251
QLabel *label = new QLabel("Здорого эт Юникод", 0);
label->show();
return app.exec();
}
…………………….
Результат выполнения: Здорого эт Юникод.
Заключение:
Для изменения и установки какой-либо требуемой кодировки используется класс QTextCodec;
Для изменения кодировки QObject::tr (функция static QString tr) используется функция QTextCodec::setCodecForTr()
Для изменения отображения кодировки символов на локале QTextCodec::setCodecForLocale()
Создали простой проект на Qt :
…………….
#include "testa1.h"
#include "QtGui"
#include "QApplication"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel *label = new QLabel("Здорого эт Юникод", 0);
label->show();
return app.exec();
}
…..
И отобразится что-то вроде -- Çäîðîãî ýò Þíèêîä;
Для нормального отображения нужно сделать следующее, в Qt есть специальный класс QTextCodec проще говоря нам нужно установить в нашем проекте другую кодировку, для этого воспользуемся функцией setCodec();
QTextCodec* codec = QTextCodec::codecForName("CP1251");//создаем указатель на QTextCodex и говорим что его кодировка "cp1251"
QTextCodec::setCodecForCStrings(codec);//устанавливаем для строк CString кодировку cp1251
……………………………………
#include "testa1.h"
#include "QtGui"
#include "QApplication"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextCodec* codec = QTextCodec::codecForName("CP1251");
QTextCodec::setCodecForCStrings(codec);
QTextCodec* codec = QTextCodec::codecForName("CP1251");//создаем указатель на QTextCodex и говорим что его кодировка "cp1251"
QTextCodec::setCodecForCStrings(codec);//устанавливаем для строк CString кодировку cp1251
QLabel *label = new QLabel("Здорого эт Юникод", 0);
label->show();
return app.exec();
}
…………………….
Результат выполнения: Здорого эт Юникод.
Заключение:
Для изменения и установки какой-либо требуемой кодировки используется класс QTextCodec;
Для изменения кодировки QObject::tr (функция static QString tr) используется функция QTextCodec::setCodecForTr()
Для изменения отображения кодировки символов на локале QTextCodec::setCodecForLocale()
Подписаться на:
Сообщения (Atom)