Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > C++ > C/C++ Базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы
Старый 01.06.2018, 20:46   #11
alexzk
Участник клуба
 
Регистрация: 12.04.2017
Сообщений: 889
Репутация: 172
По умолчанию

Цитата:
Сообщение от JUDAS Посмотреть сообщение
alexzk. Во первых спасибо за ответы.
Во вторых, я по жизни практический человек. Если заказчик просит меня создать приложение которое отображает в табличке фамилии сотрудников компании, а во второй табличке из зароботные платы по месяцам, то 90% своих усилий я бросаю на то, чтобы создать структуру БД и написать приложение удобное для пользователя... В среде QT мне приходится 90% своего времени работать с какими то не нужными мне свойствами и моделями, чтобы создать примитивный аналог компоненты DbGrid и 10% времени остаётся на саму предметную область задачи.
Считаю что допиливанием компонент и перманетной пересборкой ядра должны заниматься люди, которые без этих деяний не могут прожить и дня своей жизни.
К сожалению, я к таим людям не отношусь.... травма говорите - можете так называть готовую компоненту, которая позволяет программисту думать о поставленной задаче а не о прелестях допиливания Линукс.

п.с. Qt4 под Windows это жесть жестяная. Очень жалею тех людей, которые занимаются изобретением велосипеда в Винде изобретённого лет 20 назад.
Насколько я помню, DBGrid там и был плохонастраиваемый компонент для узкой задачи. Никто вам не мешает использовать без модельный QTableWidget (http://doc.qt.io/qt-5/qtablewidget.html#details), самостоятельно исполнять скл и заполнять поля.

Но, как показывает практика, сэкономиш здесь, будет валом проблем через 3 мес.
alexzk вне форума   Ответить с цитированием
Старый 02.06.2018, 10:41   #12
JUDAS
фонатик DELPHI
Участник клуба
 
Аватар для JUDAS
 
Регистрация: 14.01.2008
Адрес: Украина
Сообщений: 703
Репутация: 166
По умолчанию

спасибо alexzk, SAMOUCHKA и Alex11223 за ответы. Будем изобретать то, что Борланд изобрёл до моего рождения.
__________________
95% сбоев и ошибок приложений, находится в полу метрах от монитора
JUDAS вне форума   Ответить с цитированием
Старый 03.06.2018, 21:56   #13
SAMOUCHKA
Участник клуба
 
Регистрация: 07.08.2011
Адрес: Димитровград
Сообщений: 561
Репутация: 126

skype: ilya10009
По умолчанию

пока делать было не чего запилил по быстрому нечто подобное.
В программе две таблицы. Таблица рабочих, в ней id и имя работника. Таблица рабочих часов работника, в ней дата и количество отработаных часов.
Все это стандартные компоненты QTableView и к ним модель QSqlQueryModel безо всяких допиливаний, используются как есть.

Код комментировал как только можно, так что думаю все будет понятно.
заголовочный файл
Код:

#ifndef WIDGET_H
#define WIDGET_H

#include <QSqlDatabase>
#include <QWidget>
#include <QTableView>
#include <QPushButton>
#include <QDoubleSpinBox>
#include <QDateEdit>
#include <QLineEdit>
#include <QSqlQueryModel>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

private:
    // Подключение к БД, создание таблиц
    bool connectDatabase();

private slots:
    // Слот добавления нового работника
    void onAddWorker();

    // Слот добавления рабочих часов
    void onAddHours();

    // Слот обработки кликанья мышью по таблице работников
    void onWorkerTableClicked(QModelIndex index);

private:
    QSqlDatabase database;

    QTableView *table_workers; // Таблица работников
    QTableView *table_hours;  // Таблица часов

    QLineEdit *le_name_worker; // Однострочное поле ввода имени работника

    QPushButton *btn_add_worker; // Кнопка добавления работника
    QPushButton *btn_add_hour; // Кнопка добавления часов

    QDateEdit *date_edit; // Дата работы

    QDoubleSpinBox *sb_hours; // Спинбокс добавления часов

    QSqlQueryModel *model_workers; // Модель работников
    QSqlQueryModel *model_hours; // Модель часов

    QString current_id_worker;
};

#endif // WIDGET_H

.cpp
Код:

#include "widget.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QDate>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // Устанавливаем заголовок окна
    setWindowTitle("Tabel");

    // Подключаемся к базе данных
    if(!connectDatabase())
        return;

    table_workers = new QTableView;
    connect(table_workers, SIGNAL(clicked(QModelIndex)), this, SLOT(onWorkerTableClicked(QModelIndex)));

    table_hours = new QTableView;

    le_name_worker = new QLineEdit;

    btn_add_worker = new QPushButton("Add worker");
    connect(btn_add_worker, SIGNAL(clicked()), this, SLOT(onAddWorker()));

    btn_add_hour = new QPushButton("Add hours");
    connect(btn_add_hour, SIGNAL(clicked()), this, SLOT(onAddHours()));

    date_edit = new QDateEdit;
    date_edit->setDate(QDate::currentDate());

    sb_hours = new QDoubleSpinBox;
    sb_hours->setSuffix(" h");
    sb_hours->setMaximum(24);

    QVBoxLayout *vb_left = new QVBoxLayout;
    vb_left->addWidget(table_workers);
    QHBoxLayout *hb_left = new QHBoxLayout;
    hb_left->addWidget(new QLabel("name worker: "));
    hb_left->addWidget(le_name_worker);
    vb_left->addLayout(hb_left);
    vb_left->addWidget(le_name_worker);
    vb_left->addWidget(btn_add_worker);
    QVBoxLayout *vb_right = new QVBoxLayout;
    vb_right->addWidget(table_hours);
    QHBoxLayout *hb_right = new QHBoxLayout;
    hb_right->addWidget(date_edit);
    hb_right->addWidget(sb_hours);
    hb_right->addWidget(btn_add_hour);
    vb_right->addLayout(hb_right);
    QHBoxLayout *hb = new QHBoxLayout;
    hb->addLayout(vb_left);
    hb->addLayout(vb_right);
    setLayout(hb);

    model_workers = new QSqlQueryModel(this);
    table_workers->setModel(model_workers);
    model_workers->setQuery("SELECT id, name_worker FROM workers_table");
    // Подгоняем ширину колонок под контент
    table_workers->resizeColumnsToContents();

    model_hours = new QSqlQueryModel(this);
    table_hours->setModel(model_hours);
}

Widget::~Widget()
{
}

bool Widget::connectDatabase()
{
    database = QSqlDatabase::addDatabase("QSQLITE");

    database.setDatabaseName("database_tabel.sql");


    // открываем БД, проверяем ошибки
    if(!database.open())
    {
        // Выводим сообщение об ошибке и выходим
        QMessageBox::information(this, " SQL ERROR", database.lastError().text());
        return false;
    }

    // Проверяем существует ли таблица workers_table, если нет создаем ее.
    if(!database.tables().contains("workers_table"))
    {
        QSqlQuery query;
        QString str = "CREATE TABLE workers_table (id INTEGER PRIMARY KEY AUTOINCREMENT"
                      ", name_worker VARCHAR(20));";
        if(!query.exec(str))
        {
            QMessageBox::information(this, "SQL ERROR", query.lastError().text());
            return false;
        }
        qDebug()<<"CREATE TABLE workers_table";
    }

    // Проверяем существует ли таблица hours_table, если нет создаем ее.
    if(!database.tables().contains("hours_table"))
    {
        QSqlQuery query;
        QString str = "CREATE TABLE hours_table (id INTEGER PRIMARY KEY AUTOINCREMENT, "
                      "id_worker INTEGER, "
                      "date_w VARCHAR(10), "
                      "hours_w VARCHAR(2));";
        if(!query.exec(str))
        {
            QMessageBox::information(this, "SQL ERROR", query.lastError().text());
            return false;
        }
        qDebug()<<"CREATE TABLE hoers_table";
    }

    return true;
}

void Widget::onAddWorker()
{
    QString str_name = le_name_worker->text();

    // Если поле ввода имени пустое, выводим сообщение о ошибке
    if(str_name.isEmpty())
    {
        QMessageBox::information(this, "", "enter the name of the worker");
        return;
    }

    le_name_worker->clear();

    QSqlQuery query;
    QString str_query = "INSERT INTO workers_table (name_worker) "
                        "VALUES ('" + str_name + "');";
    if(!query.exec(str_query))
    {
        QMessageBox::information(this, "SQL ERROR", query.lastError().text());
        return;
    }
    model_workers->setQuery("SELECT *FROM workers_table");

    table_workers->resizeColumnsToContents();
}

void Widget::onAddHours()
{
    QSqlQuery query;
    QString str_query = "INSERT INTO hours_table (id_worker, date_w, hours_w) "
                        "VALUES ("
                        "'" + current_id_worker + "', "
                        "'" + date_edit->date().toString("yyyy_MM_dd") + "', "
                        "'" + QString::number(sb_hours->value()) + "'"
                        ");";
    if(!query.exec(str_query))
    {
        QMessageBox::information(this, "SQL ERROR", query.lastError().text());
        return;
    }

    model_hours->setQuery("SELECT date_w, hours_w FROM hours_table WHERE id_worker = " + current_id_worker +
                          " ORDER BY date_w;");

    date_edit->setDate(QDate::currentDate());
}

void Widget::onWorkerTableClicked(QModelIndex index)
{
    current_id_worker = model_workers->data(model_workers->index(index.row(), 0)).toString();

    model_hours->setQuery("SELECT date_w, hours_w FROM hours_table WHERE id_worker = " + current_id_worker +
                          " ORDER BY date_w;");
}

может несколько аляписто, но все это для примера, по быстрому на коленке.

вы интересовались как связать две таблицы. собственно это происходит в слоте
Код:

void Widget::onWorkerTableClicked(QModelIndex index)
{
    current_id_worker = model_workers->data(model_workers->index(index.row(), 0)).toString();

    model_hours->setQuery("SELECT date_w, hours_w FROM hours_table WHERE id_worker = " + current_id_worker +
                          " ORDER BY date_w;");
}

Изображения
Тип файла: png tabel.png (7.1 Кб, 10 просмотров)
__________________
eremeew.ilya@yandex.ru
SAMOUCHKA вне форума   Ответить с цитированием
Старый 05.06.2018, 20:47   #14
JUDAS
фонатик DELPHI
Участник клуба
 
Аватар для JUDAS
 
Регистрация: 14.01.2008
Адрес: Украина
Сообщений: 703
Репутация: 166
По умолчанию

Самоучка, благодарю.
Общий принцип понял. Буду пробовать
__________________
95% сбоев и ошибок приложений, находится в полу метрах от монитора
JUDAS вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Связь Master - Detail vVladislav Помощь студентам 0 31.12.2016 15:46
fibplus master-detail условие в detail tarakan1983 БД в Delphi 15 02.11.2014 17:10
Combobox и Master-Detail Максим1818 БД в Delphi 4 13.02.2014 10:10
Master Detail. добавление редактирование t.baychorov БД в Delphi 1 10.12.2011 14:23
Master-detail DELPHI+FIREBIRD Liones БД в Delphi 1 30.11.2010 14:27


18:04.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru