Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Qt
Войти
Регистрация
Восстановить пароль
 
 
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
#1

MVVM в QT. Реально ли в данное время? - C++ Qt

11.01.2018, 17:28. Просмотров 697. Ответов 23
Метки нет (Все метки)

Привет всем. Интересует вопрос. Насколько продуктивно на данном этапе времени используют архитектурный паттерн MVVM в QT? Можно ли привязывать свойства из ViewModel к свойствам контролов? На сколько это практично? Как обстоит дело с командами, которые будут вызываться со стороны View?
Вообще, кто-нибудь использует в QT паттерн MVVM для разработки приложений?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.01.2018, 17:28
Я подобрал для вас темы с готовыми решениями и ответами на вопрос MVVM в QT. Реально ли в данное время? (C++ Qt):

Действительно ли java на данное время самый актуальный язык?
нужен совет профессионалов.действительно ли java на данное время самый...

Рассчитать время, при котором данное количество вещества вступит в реакцию
Ребят подсобите пожалуйста. Без понятия как делать. 2) При температуре 10C...

За какое минимальное время роботы смогут обработать данное количество деталей?
Всем добрый вечер. Есть такая задача: На некотором заводе решили...

Рассчитать время, за которое катер пройдёт данное расстояние против течения и по течению
Разработать, ввести в ЭВМ и отладить программу для расчёта времени, за которое...

Найти заряд, протекший по соленоиду за данное время при замыкании витков соленоида сопротивлением
В магнитном поле с индукцией, изменяющейся со скоростью 4 млТл/с, находится со-...

Команда или макрокоманда "Обновить" в данное время недоступна
При нажатие кнопки на форме обновить даные выскакивает ошибка "Команда или...

23
TRam_
зомбяк
604 / 609 / 192
Регистрация: 14.05.2017
Сообщений: 2,047
11.01.2018, 18:49 #2
Для Qt, при использовании сигналов-слотов, более рациональным будет MVP, чем MVVM. В представителе (обычно он же является классом окна или диалога) реализуется создание и разрушение связей между видом (базовым виджетом окна, в котором в public'е доступны все виджеты) и моделью.

Добавлено через 10 минут
А если речь вообще о моделях, то есть QAbstractItemModel и QAbstractTableModel + куча зависимых от них, и специализированные виждеты для работы с такими моделями (QTableView, QListView, QTreeView ...). Одно у другому подключается одним вызовом, наподобие
C++ (Qt)
1
treeView1->setModel(&mymodel1);
и эта связь уже будет работать в обе стороны (как редактирование в виджете, так и обновление в модели)

Добавлено через 23 минуты
А по поводу QML - https://habrahabr.ru/post/302428/
2
Digital_Cry
Заблокирован
11.01.2018, 19:50 #3
паттерны... ох уж эти паттерны... подобными словами бросаются только студенты и преподы на экзаменах, в реальности в продакшене каждый пишет как хочет, по своему и в зависимости от ситуации
0
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
11.01.2018, 20:16  [ТС] #4
TRam_,
Цитата Сообщение от TRam_ Посмотреть сообщение
Для Qt, при использовании сигналов-слотов, более рациональным будет MVP, чем MVVM. В представителе (обычно он же является классом окна или диалога) реализуется создание и разрушение связей между видом (базовым виджетом окна, в котором в public'е доступны все виджеты) и моделью.
чем это отличается от просто событийно-управляемого подхода? Все грубо говоря в code-behind.

Цитата Сообщение от TRam_ Посмотреть сообщение
А если речь вообще о моделях, то есть QAbstractItemModel и QAbstractTableModel + куча зависимых от них, и специализированные виждеты для работы с такими моделями (QTableView, QListView, QTreeView ...). Одно у другому подключается одним вызовом, наподобие
C++ (Qt)
1
treeView1->setModel(&mymodel1);
Так, ну это уже на что-то более менее похоже. А как свойства связываются у контролов с "свойствами"(или как они там будут называться) в модели? Или там как-то все по другому?

Добавлено через 1 минуту
Digital_Cry, Ну не скажи. Вопрос на сколько ты изучил разные подходы к решению определенных задач. Я, например, пока учусь, стараюсь брать реальные задачи, и выполнить их как можно более правильно. Как только выйду на свободу, думаю эти знания пригодятся

Добавлено через 19 минут
TRam_, А что Вы скажете по поводу этого http://antyadev.blogspot.ru/2012/07/mvvm-with-qt-quick.html
0
TRam_
зомбяк
604 / 609 / 192
Регистрация: 14.05.2017
Сообщений: 2,047
11.01.2018, 20:20 #5
Цитата Сообщение от Bretbas Посмотреть сообщение
TRam_, А что Вы скажете по поводу этого
Более подробно об этом же (о QML) - в разных частях той статьи, что по ссылке в моём посте.
1
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
11.01.2018, 20:33  [ТС] #6
TRam_, Блин, там как-то все сложно написано. Я так понял, он делает какой-то мини-фреймфорк, для того, чтобы в QML иметь доступ к данным модели? Если честно, я половину не понял, что он имел ввиду
0
TRam_
зомбяк
604 / 609 / 192
Регистрация: 14.05.2017
Сообщений: 2,047
11.01.2018, 20:34 #7
Если делать без QML, то связывание будет состоять из соединения сигналов-слотов. Ну например для того, чтобы обновлять состояние QLineEdit'а, нужно объявить в модели некий сигнал, а в представителе соединить его со слотом void setText(const QString &) ( http://doc.qt.io/qt-5/qlineedit.html#text-prop ) . Для обратного (реакции на изменение пользователем) в модели объявить слот обработки строки из QLineEdit'а, а в представителе - связать его с сигналом void QLineEdit::textEdited(const QString &text) .
0
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
12.01.2018, 20:43  [ТС] #8
TRam_, ну это то все вроде бы понятно

Добавлено через 23 часа 58 минут
TRam_, Блин, я все таки не могу понять, как правильнее сделать. Подскажи пожалуйста.

Вот я написал небольшую программку на MVVM: 3 поля ввода - Имя, Фамилия, Возраст. По нажатию на кнопку, нужно отобразить Имя, Фамилию и возраст в одной строке в контроле Text. Для решение поставленной задачи, сделал MainViewModel( Для упрощения примера, данные внес прям в VM ):
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
class WindowViewModel : public QObject
{
    Q_OBJECT
public:
    explicit WindowViewModel(QObject *parent = nullptr);
 
    // Properties
    Q_PROPERTY(QString Name READ getName WRITE setName NOTIFY NameChanged)
    Q_PROPERTY(QString Surname READ getSurname WRITE setSurname NOTIFY SurnameChanged)
    Q_PROPERTY(int Age READ getAge WRITE setAge NOTIFY AgeChanged)
    Q_PROPERTY(QString Result READ getResult WRITE setResult NOTIFY ResultChanged)
 
    // Commands
    Q_INVOKABLE void command()
    {
        QString Age = QString::fromStdString(std :: to_string(_age));
        setResult(_name + " " + _surname + " " + Age);
    }
 
    // Getters/Setters
    inline QString  getName()
    {
        return _name;
    }
    inline void     setName(const QString& name)
    {
        _name = name;
        emit NameChanged();
    }
 
    inline QString  getSurname()
    {
        return _surname;
    }
    inline void     setSurname(const QString& surname)
    {
        _surname = surname;
        emit SurnameChanged();
    }
 
    inline int      getAge()
    {
        return _age;
    }
    inline void     setAge(const int& age)
    {
        _age = age;
        emit AgeChanged();
    }
 
    inline QString  getResult()
    {
        return _result;
    }
    inline void     setResult(const QString& result)
    {
        _result = result;
        emit ResultChanged();
    }
 
 
signals:
    void NameChanged();
    void SurnameChanged();
    void AgeChanged();
    void ResultChanged();
 
public slots:
 
private:
    QString _name;
    QString _surname;
    int     _age;
    QString _result;
};
Затем создал окно, добавил компоновку Column, ввел 3 TextInput'а, кнопку и контрол Text. Затем все подвязал между собой:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    Column {
        id: column
        anchors.horizontalCenter: parent.horizontalCenter
    
        TextEdit {
            
            id: nameInput
            font.pixelSize: 12
    
            text: model.Name
            Binding { target: model; property: "Name"; value: nameInput.text }
        }
    
        TextEdit {
            id: surnameInput
            font.pixelSize: 12
    
            text: model.Surname
            Binding { target: model; property: "Surname"; value: surnameInput.text }
        }
    
        TextEdit {
            id: ageInput
            font.pixelSize: 12
    
            text: model.Age
            Binding { target: model; property: "Age"; value: ageInput.text }
        }
    
        Rectangle
        {
            width: 100
            height:20
            color:"Red"
    
            Text
            {
                anchors.centerIn: parent
                text: "моя кнопка"
            }
    
            MouseArea
            {
                anchors.fill: parent
                onClicked: model.command()
            }
        }
    
        Text
        {
            id: result
            width:200
            height:30
            color: "Green"
            text: model.Result
        }
    
}
Ну и в main.cpp определил у главного контекста новое свойство modelи задал его как MainViewModel:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
int main(int argc, char *argv[])
{
...
    QQmlApplicationEngine engine;
    auto rootContext = engine.rootContext();
    rootContext -> setContextProperty( "model", new WindowViewModel());
 
...
    return app.exec();
}
Все работает. Все замечательно.

Интересуют вопросы:
1. Чем такой вариант плох?
2. Можно ли избавиться от такого ужасного объявления свойств? Хотя бы чтобы не задавать эти getters/setters?
3. Если есть у кого-нибудь свободные 10 минут, покажите как сделать этот же пример, только с более культурным подходом, которые используют на QT
0
alexu_007
142 / 153 / 34
Регистрация: 29.05.2015
Сообщений: 1,094
13.01.2018, 10:46 #9
Main.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <QtGui/QApplication>
#include "widget.h"
#include <QTextCodec>
 
int main(int argc, char *argv[])
{
 
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("cp1251"));
 
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
}
widget.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
    
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    
private:
    Ui::Widget *ui;
 
public slots:
    void text_changed();
    void press_pbtn_01();
};
 
#endif // WIDGET_H
widget.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "widget.h"
#include "ui_widget.h"
 
 
 
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    QObject::connect(ui->lineEdit_1, SIGNAL(textChanged(QString)), this, SLOT(text_changed()));
    QObject::connect(ui->lineEdit_2, SIGNAL(textChanged(QString)), this, SLOT(text_changed()));
    QObject::connect(ui->lineEdit_3, SIGNAL(textChanged(QString)), this, SLOT(text_changed()));
 
    QObject::connect(ui->pbtn_01, SIGNAL(clicked()), this, SLOT(press_pbtn_01()));
}
 
 
 
Widget::~Widget()
{
    delete ui;
}
 
 
 
void Widget::text_changed()
{
    QString str1 = ui->lineEdit_1->text();
    QString str2 = ui->lineEdit_2->text();
    QString str3 = ui->lineEdit_3->text();
 
    if((str1 != "")&&(str2 != "")&&(str3 != "")) ui->pbtn_01->setEnabled(true);
    else ui->pbtn_01->setEnabled(false);
}
 
 
 
 
void Widget::press_pbtn_01()
{
    QString str = ui->lineEdit_1->text() + " " +
                        ui->lineEdit_2->text() + " " +
                            ui->lineEdit_3->text();
 
    ui->label_4->setText(str);
}
0
Миниатюры
MVVM в QT. Реально ли в данное время?  
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
13.01.2018, 11:12  [ТС] #10
alexu_007, Вы наверное не поняли что я хотел увидеть. Я хотел увидеть правильное разделение Представления от Модели. Например в платформе .Net, есть такая технология, которая похожа на QT quick, называется она WPF. Эта технология позволяет разделить декларативное описания UI от логики приложения. Так как в WPF присутствовали "привязки данных", то замечательным решением написания десктопных приложений, было использования паттерна MVVM, который является выродком от нашего любимого MVC. Так вот, писал я, писал на WPF + MVVM. Тут вздумал перейти на QT. Увидел QT Quick, QML, и все такое...обрадовался, подумал, что можно будет писать все также, как я писал на WPF. Но не тут то было...
Моя попытка реализации программы, которую я написал выше, с использованием MVVM подхода на QT Quick, не дала хороших результатов:
Во-первых, свойства...да, в C++ их нет, но вот эти страшные подобные "свойства", которые предоставляет мне QT, никуда не годятся. А, увы, в MVVM без свойств никуда.
Во-вторых, какие-то страшные привязки в QML, по сравнению с XAML. Попахивает костылями.
В-третьих, все говорят, что в QT не применяется MVVM, нужно использовать что-то другое. Но что? Написали что MVP. Вот я бы хотел услышать вариант той же программы, только с тем подходом, который применяется чаще всего на QT, и будет соответствовать естественному отделению Представления от Модели

Тот вариант, который Вы написали, никуда не годиться. Слишком тесная связь между View и Model. Это обычных событийно-управляемый подход - все пишем в Code-Behind, и все будет здорово. Нет...так не пойдет. Я уже с этим сталкивался, больше не хочу
0
Digital_Cry
Заблокирован
13.01.2018, 11:17 #11
Цитата Сообщение от Bretbas Посмотреть сообщение
. Я хотел увидеть правильное разделение Представления от Модели
QML - это уже разделение как ты выразился модели от данных. Модель на C++, отображение на QML

Давай в двух словах, чего тебе нужно, лень читать весь блок сверху

Эй Кот, приём
0
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
13.01.2018, 11:33  [ТС] #12
Digital_Cry,
Цитата Сообщение от Digital_Cry Посмотреть сообщение
QML - это уже разделение как ты выразился модели от данных. Модель на C++, отображение на QML
Я согласен. Но если приложение большое, нужно этим разделением уметь пользоваться. Но благо, что люди уже за нас подумали, и ввели архитектурные паттерны, которые решают эту проблему

Цитата Сообщение от Digital_Cry Посмотреть сообщение
Давай в двух словах, чего тебе нужно
Мне нужно научиться писать кроссплатформенные приложения
0
Digital_Cry
Заблокирован
13.01.2018, 11:50 #13
Цитата Сообщение от Bretbas Посмотреть сообщение
Но благо, что люди уже за нас подумали, и ввели архитектурные паттерны, которые решают эту проблему
когда перейдёшь от проектирования сферического коня в вакууме и перейдёшь к коммерческой разработке, все эти глупости отпадут сами собой )
Цитата Сообщение от Bretbas Посмотреть сообщение
Мне нужно научиться писать кроссплатформенные приложения
Ты их уже пишешь, установив Qt, если конечно в коде ты не добавляешь #include <windows.h>
0
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
13.01.2018, 11:55  [ТС] #14
Digital_Cry,
Цитата Сообщение от Digital_Cry Посмотреть сообщение
когда перейдёшь от проектирования сферического коня в вакууме и перейдёшь к коммерческой разработке, все эти глупости отпадут сами собой )
Что ты предлагаешь? Где я нахожусь, пока не приступить к коммерческой разработки
0
alexu_007
142 / 153 / 34
Регистрация: 29.05.2015
Сообщений: 1,094
13.01.2018, 12:09 #15
Цитата Сообщение от Bretbas Посмотреть сообщение
3 поля ввода - Имя, Фамилия, Возраст. По нажатию на кнопку, нужно отобразить Имя, Фамилию и возраст в одной строке в контроле Text.
Я так и сделал. Плюс добавил, чтобы нельзя было вывести в строку, пока все 3 поля не заполнены. Это бонус от меня. Какая задача, такое и решение.
0
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
13.01.2018, 12:21  [ТС] #16
alexu_007, Не вырывай из контекста.
Цитата Сообщение от Bretbas Посмотреть сообщение
Вот я написал небольшую программку на MVVM: 3 поля ввода - Имя, Фамилия, Возраст. По нажатию на кнопку, нужно отобразить Имя, Фамилию и возраст в одной строке в контроле Text
Я сказал, что я написал небольшую программку.

А вопрос мой заключался вот в чем
Цитата Сообщение от Bretbas Посмотреть сообщение
Если есть у кого-нибудь свободные 10 минут, покажите как сделать этот же пример, только с более культурным подходом, которые используют на QT
культурный подход я имел ввиду использования архитектурного паттерна, который применяется чаще всего на QT.

Вы мне показали просто обычный событийно-управляемый подход. Модель и Представление все в одной куче
0
Dmitriy_M
1412 / 1295 / 126
Регистрация: 20.03.2009
Сообщений: 4,617
Записей в блоге: 11
13.01.2018, 17:44 #17
К сожалению MVVM не взлетел, да же в мире JS, что тут говорить про C++.
0
Digital_Cry
Заблокирован
13.01.2018, 18:48 #18
Цитата Сообщение от Bretbas Посмотреть сообщение
Что ты предлагаешь
джуном на работу иди.
0
Bretbas
Каждому свое
518 / 204 / 81
Регистрация: 05.08.2013
Сообщений: 1,610
Завершенные тесты: 2
13.01.2018, 21:07  [ТС] #19
Digital_Cry,
Цитата Сообщение от Digital_Cry Посмотреть сообщение
джуном на работу
Я в местах лишения свободы. Каким нахрен джуниорам Тут максимимум ручки к пакетам можно при...делывать

Добавлено через 1 минуту
Dmitriy_M,
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
К сожалению MVVM не взлетел, да же в мире JS, что тут говорить про C++.
Покажите пожалуйста, что можно и как использовать на QT?
0
Digital_Cry
Заблокирован
13.01.2018, 21:59 #20
Цитата Сообщение от Bretbas Посмотреть сообщение
Я в местах лишения свободы
с этого и надо было начинать, надеюсь не за убийство срок мотаешь?
Всех пойму, но если не ради своей выгоды лишил жизни человека.
0
13.01.2018, 21:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.01.2018, 21:59
Привет! Вот еще темы с решениями:

Команда или макрокоманда "УдалитьЗапись" в данное время недоступна
Подскажите пожалуйста, как решить проблему! Создала базу данных, и при...

Ошибка "файл используется в данное время"
FileInfo f = new FileInfo(&quot;d:\\Mytext.txt&quot;); if (f.Exists ==...

К четным элементам целочисленного массива прибавить данное число а, а из элементов с четными номерами вычесть данное число b.
К четным элементам целочисленного массива прибавить данное число а, а из...

Run-time error 2046: "Команда "Применить фильтр" в данное время недоступна"(ACCESS 2007)
Всем привет! При старте программы запускается форма с таблицей, в процедуре...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru