crossplatform.ru

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


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

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

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


Последние 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 Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 11:56