Форум Русскоязычных Скретчеров

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Форум Русскоязычных Скретчеров » Программирование » Помощь по скриптам » Как сделать динамический список на Qt Quick?


Как сделать динамический список на Qt Quick?

Сообщений 1 страница 12 из 12

1

Кто-нибудь знает как сделать динамический через C++ список на Qt Quick?

Если убрать всё что для ответа не нужно вот что у меня сейчас написано:

// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("SuperMatrixClient", "Main");

    return app.exec();
}

// Main.qml
import QtQuick
Window {
    width: 640
    height: 480
    visible: true
    title: "Matrix Client"
    color: palette.window
    ListView {
        id: messageView
        Layout.topMargin: 10
        Layout.fillWidth: true
        Layout.fillHeight: true
        Layout.preferredWidth: 500
        model: ListModel {
            ListElement {
                message: "sfsfdsdf"
                ismine2: false
                upgroup: false
                downgroup: true
            }
            ListElement {
                message: "sdf"
                ismine2: false
                upgroup: true
                downgroup: false
            }
            ListElement {
                message: "fjklkj"
                ismine2: true
                upgroup: false
                downgroup: false
            }
        }
        delegate: MessageBubble {
            // Этот тип из файла MessageBubble.qml, который я не показал
            required property string message
            required property bool ismine2
            required property bool upgroup
            required property bool downgroup
            text2: message
            ismine: ismine2
            upgroup2: upgroup
            downgroup2: downgroup
        }
        spacing: 5
    }
}

Подпись автора

Я администратор. Я сделал очень много вещей, например кнопку чата сверху (кстати заходите, если хотите дам вам пароль от пробного аккаунта), отправку файлов (через тот чат, не удаляйте пробный аккаунт пожалуйста, иначе отправка файлов перестанет работать), тёмную тему, нормальное цитирование, выбор смайликов и многое другое.
MatrixMastodo… ой то есть Misskey
[html]<iframe src="https://shitpost.poridge.club/embed/user-timeline/a7w5npj75y?maxHeight=300" data-misskey-embed-id="v1_f2e81845-9b9f-4b1c-a8f8-4edd40b0171c" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; width: 500px; height: 300px; color-scheme: light dark;"></iframe>
<script defer src="https://shitpost.poridge.club/embed.js"></script><a href=https://www.calend.ru target=_blank style="display: inline; position: absolute; margin-left: 20px;"><img src="https://www.calend.ru/img/export/informer.png" width="189" alt="Праздники сегодня" border="0"></a>[/html]

0

2

Gregon написал(а):

(#1)
Кто-нибудь знает как сделать динамический через C++ список на Qt Quick?

Если убрать всё что для ответа не нужно вот что у меня сейчас написано:

Ну ты задал вопрос. На Qt давно ничего не делал. Да, и раньше не было qml скриптов. Вся программа писалась на C++.
Попробую, что помню написать.
Для добавлении элементов в C++ можно использовать список QList: https://doc.qt.io/qt-6/qlist.html
Пример:

Код:
QList<QString> list;
list.append("one");
list.append("two");
QString three = "three";
list.append(three);
// list: ["one", "two", "three"]
// three: "three"

Для добавления/удаления элементов в QML может использоваться методы append, delete: https://doc.qt.io/qt-6/qml-qtqml-models-listmodel.html

Код:
fruitModel.append(..., "attributes":
    [{"name":"spikes","value":"7mm"},
     {"name":"color","value":"green"}]);
fruitModel.get(0).attributes.get(1).value; // == "green"

Не сильно густо. Но с qml практически не работал.
Если нужно - могу попробовать поискать пример программы.

0

3

Посмотри, возможно, это то что ты ищешь: https://doc.qt.io/qt-6/qtquick-modelvie … odels.html

0

4

Qt какой-то слишком сложный, я уже 4 часа пытаюсь понять как сделать сделать через C++ список и при этом его можно было менять пока программа запущена и до сих пор ничего не получилось

3DArte написал(а):

(#3)
Посмотри, возможно, это то что ты ищешь: https://doc.qt.io/qt-6/qtquick-modelvie … odels.html

Я не понял как это впихнуть в мою программу…

Подпись автора

Я администратор. Я сделал очень много вещей, например кнопку чата сверху (кстати заходите, если хотите дам вам пароль от пробного аккаунта), отправку файлов (через тот чат, не удаляйте пробный аккаунт пожалуйста, иначе отправка файлов перестанет работать), тёмную тему, нормальное цитирование, выбор смайликов и многое другое.
MatrixMastodo… ой то есть Misskey
[html]<iframe src="https://shitpost.poridge.club/embed/user-timeline/a7w5npj75y?maxHeight=300" data-misskey-embed-id="v1_f2e81845-9b9f-4b1c-a8f8-4edd40b0171c" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; width: 500px; height: 300px; color-scheme: light dark;"></iframe>
<script defer src="https://shitpost.poridge.club/embed.js"></script><a href=https://www.calend.ru target=_blank style="display: inline; position: absolute; margin-left: 20px;"><img src="https://www.calend.ru/img/export/informer.png" width="189" alt="Праздники сегодня" border="0"></a>[/html]

0

5

Gregon написал(а):

(#4)
Qt какой-то слишком сложный, я уже 4 часа пытаюсь понять как сделать сделать через C++ список и при этом его можно было менять пока программа запущена и до сих пор ничего не получилось

Попробуй начать с простых программ. Как поймешь немного архитектуру, сможет посложнее программы делать. Предлагаю пока отказаться от QML при написании программы. Как говорил, Qt раньше не использовал QML. На сколько знаю, ты и сейчас можешь сделать программу на Qt без QML: https://wiki.qt.io/Qt_for_Beginners

Вот самая простая программа на Qt:

Код:
#include <QApplication>
#include <QPushButton>

int main(int argc, char **argv)
{
 QApplication app (argc, argv);

 QPushButton button ("Hello world !");
 button.show();

 return app.exec();
}

QApplication - класс твоего приложения.
QPushButton - обычная кнопка.

А вот приложение уже со слайдером(QSlider) и прогресс баром(QProgressBar):

Код:
#include <QApplication>
#include <QProgressBar>
#include <QSlider>

int main(int argc, char **argv)
{
 QApplication app (argc, argv);

 // Create a container window
 QWidget window;
 window.setFixedSize(200, 80);

 // Create a progress bar
 // with the range between 0 and 100, and a starting value of 0
 QProgressBar *progressBar = new QProgressBar(&window);
 progressBar->setRange(0, 100);
 progressBar->setValue(0);
 progressBar->setGeometry(10, 10, 180, 30);

 // Create a horizontal slider
 // with the range between 0 and 100, and a starting value of 0
 QSlider *slider = new QSlider(&window);
 slider->setOrientation(Qt::Horizontal);
 slider->setRange(0, 100);
 slider->setValue(0);
 slider->setGeometry(10, 40, 180, 30);

 window.show();

 // Connection
 // This connection set the value of the progress bar
 // while the slider's value changes
 QObject::connect(slider, SIGNAL (valueChanged(int)), progressBar, SLOT (setValue(int)));

 return app.exec();
}

В последней программе используются сигналы и слоты(QObject::connect). Изменения ползунка слайдера вызовет изменения значение прогресс бара.
В этих программах используются базовые классы. Но так же можно расширить их функционал написав свой класс, который будет наследовать Qt класс и использовать другие классы. В своем классе, к примеру, окна можешь создать текстовое поле, кнопки и т.д.

А вот еще одно простое приложение:

Код:
#include <QApplication>
#include <QPushButton>
#include <QWidget>
#include <QVBoxLayout>

int main(int argc, char *argv[]) {
    // Create a QApplication object. This is the central object that manages the application's event loop.
    QApplication app(argc, argv);

    // Create a QWidget, which will serve as our main window.
    QWidget *window = new QWidget;
    window->setWindowTitle("Simple Qt Example");

    // Create a QPushButton.
    QPushButton *button = new QPushButton("Click Me!");

    // Create a vertical layout to arrange widgets within the window.
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(button); // Add the button to the layout.
    window->setLayout(layout); // Set the layout for the window.

    // Connect the button's clicked signal to a lambda function that prints a message.
    QObject::connect(button, &QPushButton::clicked, []() {
        qDebug("Button clicked!"); // Print to the console (requires #include <QDebug>)
        // You could also show a message box here:
        // QMessageBox::information(nullptr, "Info", "Button was clicked!");
    });

    // Show the window.
    window->show();

    // Start the application's event loop. This makes the application responsive to user input.
    return app.exec();
}

Пример последней программы сгенерирован гуглом. Надеюсь заработает из коробки) Не проверял.
С помощью вертикальных(QVBoxLayout) и горизонтальных(QVBoxLayout) ящиков можно создавать составные элементы(к примеру, текстовое поле с кнопкой). В вертикальном ящике элементы группируются по вертикали, в горизонтальном ящике соответственно - горизонтально.

Подожди, до списка тоже дойдешь. Все в этих программах понятно?

0

6

Грег, как успехи? Что-нибудь получилось сделать?

0

7

3DArte написал(а):

(#6)
Грег, как успехи? Что-нибудь получилось сделать?

Я документацию не понял и спросил ответ у нейросети, вот что выдалось:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTimer>
#include <QAbstractListModel>
#include <QColor>

// Message data structure
struct MessageData {
    QString text;
    bool isMine;
    bool upGroup;
    bool downGroup;
};

// Custom List Model
class MessageModel : public QAbstractListModel {
    Q_OBJECT
public:
    enum MessageRoles {
        TextRole = Qt::UserRole + 1,
        IsMineRole,
        UpGroupRole,
        DownGroupRole
    };

    explicit MessageModel(QObject *parent = nullptr) : QAbstractListModel(parent) {}

    int rowCount(const QModelIndex &parent = QModelIndex()) const override {
        Q_UNUSED(parent);
        return m_messages.size();
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
        if (!index.isValid() || index.row() >= m_messages.size())
            return QVariant();

        const MessageData &msg = m_messages.at(index.row());
       
        switch (role) {
        case TextRole:
            return msg.text;
        case IsMineRole:
            return msg.isMine;
        case UpGroupRole:
            return msg.upGroup;
        case DownGroupRole:
            return msg.downGroup;
        default:
            return QVariant();
        }
    }

    QHash<int, QByteArray> roleNames() const override {
        QHash<int, QByteArray> roles;
        roles[TextRole] = "messageText";
        roles[IsMineRole] = "isMine";
        roles[UpGroupRole] = "upGroup";
        roles[DownGroupRole] = "downGroup";
        return roles;
    }

    Q_INVOKABLE void addMessage(const QString &text, bool isMine, bool upGroup, bool downGroup) {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_messages.append({text, isMine, upGroup, downGroup});
        endInsertRows();
    }

    Q_INVOKABLE void clearMessages() {
        beginResetModel();
        m_messages.clear();
        endResetModel();
    }

private:
    QList<MessageData> m_messages;
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    // Create and expose the model
    MessageModel messageModel;

    // Add some initial messages
    messageModel.addMessage("sfsfdsdf", false, false, true);
    messageModel.addMessage("sdf", false, true, false);
    messageModel.addMessage("fjklkj", true, false, false);

    QQmlApplicationEngine engine;
   
    // Expose the model to QML
    engine.rootContext()->setContextProperty("messageModel", &messageModel);

    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);

    engine.loadFromModule("SuperMatrixClient", "Main");

    // Example: Add messages dynamically from C++
    QTimer::singleShot(1000, [&messageModel]() {
        messageModel.addMessage("Hello from C++ after 1 second!", true, false, true);
    });

    QTimer::singleShot(3000, [&messageModel]() {
        messageModel.addMessage("Another message after 3 seconds", false, true, false);
    });

    // Example: Add messages periodically
    QTimer *periodicTimer = new QTimer(&app);
    QObject::connect(periodicTimer, &QTimer::timeout, [&messageModel]() {
        static int counter = 1;
        messageModel.addMessage(QString("Periodic message #%1").arg(counter++),
                               counter % 2 == 0, false, false);
    });
    periodicTimer->start(5000); // Add a message every 5 seconds

    return app.exec();
}

Но я не понял зачем так много раз повторять одно и тоже название разными способами?
Я попробовал, всё вроде работает, продолжил делать.
https://upforme.ru/uploads/001c/58/e1/10/740661.png

Подпись автора

Я администратор. Я сделал очень много вещей, например кнопку чата сверху (кстати заходите, если хотите дам вам пароль от пробного аккаунта), отправку файлов (через тот чат, не удаляйте пробный аккаунт пожалуйста, иначе отправка файлов перестанет работать), тёмную тему, нормальное цитирование, выбор смайликов и многое другое.
MatrixMastodo… ой то есть Misskey
[html]<iframe src="https://shitpost.poridge.club/embed/user-timeline/a7w5npj75y?maxHeight=300" data-misskey-embed-id="v1_f2e81845-9b9f-4b1c-a8f8-4edd40b0171c" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; width: 500px; height: 300px; color-scheme: light dark;"></iframe>
<script defer src="https://shitpost.poridge.club/embed.js"></script><a href=https://www.calend.ru target=_blank style="display: inline; position: absolute; margin-left: 20px;"><img src="https://www.calend.ru/img/export/informer.png" width="189" alt="Праздники сегодня" border="0"></a>[/html]

0

8

Gregon написал(а):

(#7)
Но я не понял зачем так много раз повторять одно и тоже название разными способами?
Я попробовал, всё вроде работает, продолжил делать.

Не совсем понял про какое название пишешь?
В примере показано, как с помощью C++ и с помощью QML можно создавать сообщения. Но есть участки кода достаточно подозрительные.

С ИИ будь осторожен, сгенерированный код надо всегда проверять. Могут быть ошибки, которые потом дадут о себе знать.
Клиент для matrix собираешься написать? Или это просто эксперимент?

0

9

3DArte написал(а):

(#8)
Не совсем понял про какое название пишешь?

Там три разных типа данных для одного и того же названия

Код:
QString text;
TextRole = Qt::UserRole + 1,
roles[TextRole] = "messageText";
3DArte написал(а):

(#8)
С ИИ будь осторожен, сгенерированный код надо всегда проверять. Могут быть ошибки, которые потом дадут о себе знать.

Я обычно их не использую, это вообще единственный раз когда я их использовал для чего-то полезного.

3DArte написал(а):

(#8)
Клиент для matrix собираешься написать?

Да, просто для него есть два самых популярных клиента (Cinny и Element), но в одном (Element) неудобный дизайн, но много функций протокола поддерживаются, а в другом (Cinny) дизайн удобный, но функций мало поддерживается, вот я и решил свой написать, чтобы там и функций много было, и дизайн был удобный

Подпись автора

Я администратор. Я сделал очень много вещей, например кнопку чата сверху (кстати заходите, если хотите дам вам пароль от пробного аккаунта), отправку файлов (через тот чат, не удаляйте пробный аккаунт пожалуйста, иначе отправка файлов перестанет работать), тёмную тему, нормальное цитирование, выбор смайликов и многое другое.
MatrixMastodo… ой то есть Misskey
[html]<iframe src="https://shitpost.poridge.club/embed/user-timeline/a7w5npj75y?maxHeight=300" data-misskey-embed-id="v1_f2e81845-9b9f-4b1c-a8f8-4edd40b0171c" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; width: 500px; height: 300px; color-scheme: light dark;"></iframe>
<script defer src="https://shitpost.poridge.club/embed.js"></script><a href=https://www.calend.ru target=_blank style="display: inline; position: absolute; margin-left: 20px;"><img src="https://www.calend.ru/img/export/informer.png" width="189" alt="Праздники сегодня" border="0"></a>[/html]

0

10

Gregon написал(а):

(#7)
https://upforme.ru/uploads/001c/58/e1/10/740661.png

На аватарки не обращайте внимание, это просто заглушка пока я не сделаю загрузку аватарок, я эту картинку просто у себя в загрузках нашёл :D

Подпись автора

Я администратор. Я сделал очень много вещей, например кнопку чата сверху (кстати заходите, если хотите дам вам пароль от пробного аккаунта), отправку файлов (через тот чат, не удаляйте пробный аккаунт пожалуйста, иначе отправка файлов перестанет работать), тёмную тему, нормальное цитирование, выбор смайликов и многое другое.
MatrixMastodo… ой то есть Misskey
[html]<iframe src="https://shitpost.poridge.club/embed/user-timeline/a7w5npj75y?maxHeight=300" data-misskey-embed-id="v1_f2e81845-9b9f-4b1c-a8f8-4edd40b0171c" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; width: 500px; height: 300px; color-scheme: light dark;"></iframe>
<script defer src="https://shitpost.poridge.club/embed.js"></script><a href=https://www.calend.ru target=_blank style="display: inline; position: absolute; margin-left: 20px;"><img src="https://www.calend.ru/img/export/informer.png" width="189" alt="Праздники сегодня" border="0"></a>[/html]

0

11

Gregon написал(а):

(#9)
Там три разных типа данных для одного и того же названия

Мне сложно судить о правильности кода пока я не понимаю контекст. Что такое роль сообщения?

На сколько понял, каждое сообщение может иметь текстовое поле и дополнительные флаги, которые где-то обрабатываются(MessageData).
TextRole - это элемент энумератора, указывающий на текстовое поле сообщения. Из сообщения с помощью метода data() можно запросить текстовое поле по этому энумератору. Так же можно запросить флаги по энумераторам isMine, upGroup и downGroup.
Пример:

Код:
QString test = messageModel.data(index, TextRole);

Вроде как-то так.
Судя по коду метод roleNames() нигде не используется. И не понятно его назначение. Возможно текстовые обозначения ролей могут где-то в программе использоваться.

0

12

Gregon написал(а):

(#10)
На аватарки не обращайте внимание, это просто заглушка пока я не сделаю загрузку аватарок, я эту картинку просто у себя в загрузках нашёл :D

Ну аватарки меня давно не удивляют. Многие любят скримеры.

0

Быстрый ответ

Напишите ваше сообщение и нажмите «Отправить»



Вы здесь » Форум Русскоязычных Скретчеров » Программирование » Помощь по скриптам » Как сделать динамический список на Qt Quick?