crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Реализация многопользовательского приложения
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Litkevich Yuriy Дата 17.3.2009, 14:32
 
Цитата(LE0N @ 17.3.2009, 12:56) *
особенности простейшего примерчика
речь не идет о простейшем.

просто вопрос:
Цитата(LE0N @ 16.3.2009, 1:03) *
А как твоя модель узнает про m_query которая отпрепарилась?
не относится к теме "реализации многопользовательского приложения", это самостоятельная тема и обсуждать нужно отдельно.
LE0N Дата 17.3.2009, 9:56
 
Цитата
Давайте договоримся, в этой теме обсуждаются архитектурные особенности

Да, собственно, архитектурные особенности простейшего примерчика меня не интерисовали :)
Меня интерисовала реализация. Не хотелось писать грубыми хаками QTшных виджетов. Что, в итоге, и получилось...(Как мне показалось)
Кстати в QT имеется реализация в зародыше ActiveRecord связей... QSqlRelationalTableModel
Litkevich Yuriy Дата 16.3.2009, 2:03
 
Цитата(LE0N @ 16.3.2009, 1:03) *
Я с QT работаю 3 дня от силы....
Можно по-подробнее ?
тогда стоит почитать Программирование Модель/Представление

Давайте договоримся, в этой теме обсуждаются архитектурные особенности многопользовательского приложения с возможностью оговорок о реализации на Qt4.
А точные детали реализации на Qt обсуждаются в одноименном подфоруме, предварительно поискав в нем.
BRE Дата 15.3.2009, 22:40
 
Цитата(LE0N @ 15.3.2009, 22:03) *
А как твоя модель узнает про m_query которая отпрепарилась?

void SqlTableModel::refresh()
{
        prepareQuery();
        if( !m_query->exec() )
              // Сохранили/сообщили об ошибке
}


UserModel model;
model.refresh();

QListView list;
list.setModel( &model );

QTableView table;
table.setModel( &model );
LE0N Дата 15.3.2009, 22:03
  о_О.
А как твоя модель узнает про m_query которая отпрепарилась?
И как пользоваться вьюяхами? Это те comboBox и проч ?
Я с QT работаю 3 дня от силы....
Можно по-подробнее ?
BRE Дата 15.3.2009, 21:53
 
Цитата(LE0N @ 15.3.2009, 21:29) *
Можешь примерчиком поделиться более реальным, не таким как в экзамплах КЮТЭ....

Раскрывающийся текст

class SqlTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    SqlTableModel( QObject *parent = 0, int idColumn = 0 );
    ~SqlTableModel();
....
        int                             rowCount( const QModelIndex &parent = QModelIndex() ) const;

public slots:
    void        refresh();                             // Выполнить запрос.

protected:
    virtual    void    prepareQuery() = 0;     // Настроить запрос (вызывается из refresh). Переопределяется в наследниках и настраивает запрос.

protected:
    QSqlQuery     *m_query;
};

class UserModel : public SqlTableModel
{
        Q_OBJECT
public:
        UserModel( QObject *parent = 0 );

                        QSqlRecord      record( id_t ) const;
                        int                   add( const QString &name, const QString &password );
                        int                   edit( id_t id, const QString &name, const QString &password );
                        bool                 canDelete( id_t ) const;
                        int                   del( id_t );

        virtual QVariant                headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
        virtual QVariant                data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
        virtual int                         columnCount( const QModelIndex &parent = QModelIndex() ) const;

protected:
        virtual void    prepareQuery();
};

void UserModel::prepareQuery()
{
        m_query->prepare( "SELECT user.id, user.name, user.password FROM users" );
}

// Здесь может быть сложный запрос, который будет делать выборку из нескольких таблиц.
// Также можно настраивать ключи выборки, сортировки и т.д.


А дальше устанавливаешь эту модель в view и пользуешся. :)
LE0N Дата 15.3.2009, 21:29
 
Цитата
Я использую в качестве базы QAbstractTableModel, от него делаю свой класс SqlTableModel, а от него идут все модели.
С QSqlTableModel у меня как-то не сложилось, наверное из-за его универсальности, не нравится он мне.

Можешь примерчиком поделиться более реальным, не таким как в экзамплах КЮТЭ....
А то я немножко не понимаю логики...
    AuthForm win(this);
    QSqlTableModel *model=new QSqlTableModel(this,db);
    model->setTable("users");
    win.ui.comboBox->setModel(model);
    win.ui.comboBox->setModelColumn(1);
    this->hide();
    if(!win.exec()) {
        this->close();
        return;
    }
    this->show();

Для теста вынес ui в публичные переменные...
В комбобоксе ни чего не появляется вообще... ПУСТО...
BRE Дата 15.3.2009, 21:16
 
Цитата(LE0N @ 15.3.2009, 20:21) *
А от чего наследовать UserModel в случае с работой с базами данных? (QT)

Я использую в качестве базы QAbstractTableModel, от него делаю свой класс SqlTableModel, а от него идут все модели.
С QSqlTableModel у меня как-то не сложилось, наверное из-за его универсальности, не нравится он мне. :)
LE0N Дата 15.3.2009, 20:21
 
Цитата
В приложении мы постоянно имеет дело с самими таблицами, поэтому я остановился на создании своих моделей и работы через них, т.е. в UserModel можно добавить свои методы

А от чего наследовать UserModel в случае с работой с базами данных? (QT)
Цитата
А здесь, мне так кажется, ты зациклился на лоадере

Возможно. Просто его я уже реализовал. Вот только передачу указателей на данные из лоадера в приложение не могу придумать как реализовать...
BRE Дата 14.3.2009, 11:57
 
Цитата(LE0N @ 14.3.2009, 0:45) *
Не в идеале - вот, допустим, мы имеем таблицу пользователей.
Получаем их.
В первый раз мы получили поля username,password во второй раз id,username,password.
Тип переменной один и тот же (QSqlQuery) а данные в нём разные...Передавать в конструктор только ТО, что нужно, увеличивая число аргументов функции?
Если загонять данные через конструктор, то мы заберём оттуда только то, что требуется. А вдруг нам потребуется потом ещё и id ? Переписывать первый запрос?
Или, может быть, забирать все данные ? Только нахера забирать тот же blob или bigtext, если они не используются в данном месте....
Короче я не знаю с какой стороны подступиться...В вебе и с скриптами все дела выглядели на много проще...

Я эксперементировал с оборачиванием объектов БД в классы. Посмотрим твой пример с пользователеями...
Это можно реализовать двумя способами:
1. Делается класс User, в котором есть переменные для всех полей записи.
Конструктор без параметров создает новый объект в памяти (в БД пока ничего не создается);
Конструктор с параметром id читает в свои внутреннии переменные все поля из записи с указанным id;
Есть геттеры/сеттеры для переменных;
Есть метод flush, который в зависимости от конструктора или создает новую запись, или обновляет ее.
Выводы: даже если тебе нужно одно поле из записи закеширует все.
2. Делаем класс User, который хранит только id.
Конструктор без параметров создает новый объект в памяти и новую пустую запись в БД. Сохраняет id новой записи в себе;
Конструктор с параметром id сохраняет этот id в себе;
Геттеры на кождое поле выполняют запрос к БД и возвращают значение, сеттеры делаю запросом с сохранением данных в БД.
Выводы: если тебе нужно прочитать три поля из записи, будет вызвано три запроса.

В принципе первый вариант мне нравиться больше чем второй, но я отказался от обоих. Мне стало лениво описывать каждую запись в свой класс. Причем по хорошему для каждой таблице нужно описать еще класс типа UserTable, в котором описать работу с самой таблицей...
В приложении мы постоянно имеет дело с самими таблицами, поэтому я остановился на создании своих моделей и работы через них, т.е. в UserModel можно добавить свои методы:
QSqlRecord record( id );
int add( name, password );
int edit( id, name, password );
bool canDelete( id );
int del( id );

Методы add, edit, del - возвращают номер строки, которую нужно сделать активной в view.

Цитата(LE0N @ 14.3.2009, 0:45) *
Имеем лоадер. Который подгружает конфиги, коннектится к базе, получает (делает запрос) пользователей...
Потом мне нужно передать управление диалогу - в диалоге имеем список пользователей и их пароли.
После сверки md5 этих паролей, мне требуется передать управление, опять же, лоадеру, в который должен попасть активный пользователь...
Вот как такую хрень организовать ? Добавлять ещё переменные типа *activeUser в форму авторизации оного? И по закрытию этого окна получать его лоадером?
И что дальше? получили логин. Ещё один запрос делать для получения дополнительных данных ? Воспитан в лучших традициях и знаю, что это лишняя нагрузка.
В общем хочу подойти к этому делу основательно....
Как вы считаете, моразм?

А здесь, мне так кажется, ты зациклился на лоадере. ;)
Есть программы, которая работает с определенной конфигурацией. Вводим класс Configuration, который содержит всю информацию для работы. После конструирования MainWindow, запускается диалог выбора пользователя, после выбора пользователя создается и настраивается объект конфигурации и MainWindow начинает работать с этой конфигурацией. Пользователь нажал кнопку закончить работу, объект конфигурации разрушился и открылся диалог выбора пользователя. И т.д.
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 28.3.2024, 16:30