LINUX.ORG.RU

Эмулировать логически. То есть работать только с местами интереса (создающимися, например, после клика в определенную область) вместо создания матрицы квадратов, большая часть которых никогда использоваться не будет, а вот жрать ого-го. тыц

CrossFire ★★★★★
()
Ответ на: комментарий от CrossFire

По сути у меня интерактивная пиксельная карта с зумингом...

Т.е. тут надо наверное OpenGL подключить как-нибудь...

deterok ★★★★★
() автор топика
Ответ на: комментарий от CrossFire

Хм, сложновато...

Вернее очнь много мороки... Но вы правы, так будет гораздо быстрее...

deterok ★★★★★
() автор топика
Ответ на: комментарий от CrossFire

В общем я кажись допер, нужен объект, который будет чисто через QPainter рисовать матрицу и при клике передавать индексы (x,y) квадрата.

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

интерактивная пиксельная карта с зумингом...

OpenGL.
Один слой - с текстурами карты.
Второй - для текста и заметок.

Всё-таки лучше решать такие задачи на предназначенном для этого железе.

devl547 ★★★★★
()
Ответ на: комментарий от deterok

Объясню подробнее: пусть у нас есть базовое изображение и возможность модификации любого пикселя. Есть возможность отлавливать клики, в результате создавать объект нашего класса MyGraphRectItem хранящий h, w, x, y (это его область ответственности). Есть набор возможных анимаций, в том числе выделения, у каждого созданного айтема есть список примененных на него эффектов. Каждый раз при перерисовке мы бежим по нашему контейнеру с айтемами, и заставляем их модифицировать базовое изображение в своей области ответственности нужным образом (наложить эффект).

CrossFire ★★★★★
()
Ответ на: комментарий от CrossFire

Супер!!!

Я чего-то не допер до этого сам...

deterok ★★★★★
() автор топика
Ответ на: комментарий от CrossFire

Я немного не понял. Вот у нас ей QImage и есть наш супер итем, который должен отображать его.

При перерисовке он просто пробегается по пикселям QImage и отрисовывает их цвета с границами, тем самым достигается сетка.

При клике на него создается рект итем, задается brash и возвращается. А как быть с анимациями тогда. Ведь итем в этом не участвует получается? Вот здесь я как-то поплыл...

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Вот есть у нас QImage, на формочке хоть QLabel, хоть QML Image — который ее отображает. Вот в начальный момент времени у нас просто оригинальное изображение. Тут приходит клик с координатами:

  • Он передается в определенный класс, который в единственном экземпляре на наше изображение — назовем его Нео. Пусть у Нео есть указатель на наше изображение.
  • Нео говорит ага, пришел клик, надо создать НаноБота с определенной областью ответственности (передает в конструктор H,W,X,Y). Сразу же устанавливает НаноБоту задачу - отрисовка выделения. И кладет этого нанобота в список.
  • Допустим выделенный участок должен плавно менять цвета.
  • Через 30мс мы дергаем Нео по таймеру, говорим отрисуй нам картинку. Он бежит по своему списку, запускает НаноБотов, передавая им ссылку на изображение.
  • Каждый из них, зная свое текущее состояние, зная свою область ответственности, меняет пиксели определенным образом. Например при выделении нужно десять тактов увеличивать синий оттенок, потом десять уменьшать — получится анимация. Вот каждый НаноБот и хранит счетчик, описывающий текущее состояние, может флаг еще какой.
  • Когда список закончится, Нео вернет результирующее изображение на отрисовку. Следующий такт начнет с оригинального и натравит ботов на него.

Осталось додумать грамотную реализацию класса/метода анимаций (может паттерн какой использовать). Ну и не создавать НаноБотов на каждое касание, а сначала искать ответственного за выбранную область в списке.

CrossFire ★★★★★
()
Последнее исправление: CrossFire (всего исправлений: 1)
Ответ на: комментарий от CrossFire

Т.е. не получится заюзать готовые анимации из Qt?

deterok ★★★★★
() автор топика
Ответ на: комментарий от CrossFire

Ага, а если событие mouse move?

Все нафиг и согнется если он будет создавать и удалять объекты постоянно...

deterok ★★★★★
() автор топика
Ответ на: комментарий от CrossFire

Вообщем вот где ооп ломается...

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Ага, а если событие mouse move?

Все нафиг и согнется если он будет создавать и удалять объекты постоянно...

Ну значит побить на разумное количество кусков (даже 10*10 облегчают задачу в сто раз), создать их сразу, и не удалять никогда. А стандартные анимации да, идут лесом.

Вообщем вот где ооп ломается...

Где?

CrossFire ★★★★★
()
Последнее исправление: CrossFire (всего исправлений: 1)
Ответ на: комментарий от CrossFire

В общем большое спасибо. Помогли мне очень.

Вы не против если я вас в скором будущем помучаю еще немного? :)

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Вы не против если я вас в скором будущем помучаю еще немного? :)

Если что, контакты в профиле.

CrossFire ★★★★★
()
Ответ на: комментарий от fluorite

Ты почитай по ссылке, там и есть OpenGL и рендеринг с таймерами.

Да я почитал, в общем-то описываем НаноБота как Painted Item, режем текстуру и даем каждому из них, а анимации, вероятно, можно и из QML прикрутить. Но, с другой стороны, не факт, что на миллионах элементов Scene Graph будет быстрее вышеописанного велосипеда.

P.S. На самом деле я с графикой почти не работал, но тут задача интересная оказалась)

CrossFire ★★★★★
()
Ответ на: комментарий от CrossFire

Мне кажется, чем через пэинтер, лучше что-нибудь типа

QSGNode *PaintImageItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
    QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *> (oldNode);
    if (!node) {
        node = new QSGSimpleTextureNode;
    }

    QSGTexture *oldTexture = node->texture();
    if (oldTexture)
        delete oldTexture;

    QImage scaledImage = m_image.scaled(width(), height(), Qt::KeepAspectRatio,
                                        Qt::SmoothTransformation);
    node->setTexture(window()->createTextureFromImage(scaledImage));
    node->setRect(QRect(0, 0, scaledImage.width(), scaledImage.height()));
    return node;
}
где m_image часть текстуры.

fluorite ★★★★★
()
Ответ на: комментарий от fluorite

Вот кстати, накидал тут qml-ку (не спится чего-то). GridView на ура справляется с миллионом ректанглов.

Rectangle {
    width: 501; height: 500
    visible: true
    color: "orange"

    Flickable {
        width: gridView.width + 1; height: width
        contentWidth: 500; contentHeight: 500
        GridView {
            id: gridView
            anchors.fill: parent
            cellWidth: 100; cellHeight: 100
            model: 1000000
            delegate:
                Rectangle {
                    id: rect
                    width: 90; height: 90
                    color: "red"
                    border.width: 1
                Image {
                    width: 90; height: 90
                    anchors.centerIn: parent
                    source: "qrc:/qt-logo.png"
                    fillMode: Image.PreserveAspectFit
                }
                Text {
                    anchors.centerIn: parent
                    text: model.index
                }
                MouseArea {
                    anchors.fill: parent
                    onClicked: rect.color = "green"

                }
            }
        }
    }
}

fluorite ★★★★★
()
Ответ на: комментарий от fluorite

А если зазумить так, что бы отображались все элементы сразу?

deterok ★★★★★
() автор топика

И все это дело тупо тормозит при перемещение.

Двигаем все 9 милионов объектов разом? Вообще сложно судить, что у тебя там за задача,но может тебе поможет некое подобие MIP-уровней?

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Как бы объяснить, у меня есть картинка состоящая из пикселей разных цветов - схема. Мне нужно сделать плавный пользовательский зуминг от все пикселей на экране, до пары десятков.

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

А так?

pixelgrid.h

#ifndef PIXELGRID_H
#define PIXELGRID_H

#include <QQuickItem>
#include <QSGSimpleRectNode>
#include <QColor>

class Pixel final: public QSGSimpleRectNode
{
public:
    Pixel(const QRectF& rect, const QColor& color);
    ~Pixel();
private:
    QSGSimpleRectNode *border;
};

class PixelGrid : public QQuickItem
{
    Q_OBJECT
public:
    PixelGrid();
protected:
    QSGNode* updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
};

#endif // PIXELGRID_H
pixelgrid.cpp
#include "pixelgrid.h"

#include <QRectF>
#include <QSGSimpleRectNode>

static const QString orange("orange");
static const int pixel_width(5);
static const int pixel_height(5);

Pixel::Pixel(const QRectF &rect, const QColor &color)
    : QSGSimpleRectNode(rect, color)
    , border(new QSGSimpleRectNode)
{
    setColor(Qt::black);
    border->setRect(this->rect().adjusted(1,1,-1,-1));
    border->setColor(color);
    appendChildNode(border);
}

Pixel::~Pixel()
{
    delete border;
}

PixelGrid::PixelGrid()
{
    setFlag(ItemHasContents);
}

QSGNode *PixelGrid::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
    QSGNode *node = oldNode;
    if (!node) {
        node = new QSGSimpleRectNode(boundingRect(), QColor(orange));

        for (int i = 0; i < 1000; i = i + pixel_width) {
            for (int j = 0; j < 1000; j = j + pixel_height)
                node->appendChildNode(new Pixel(QRectF(i,j,pixel_width,pixel_height), Qt::red));
        }
    }

    return node;
}
main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>

#include "pixelgrid.h"

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

    qmlRegisterType<PixelGrid>("Pixel", 1, 0, "PixelGrid");
    QQuickView view(QUrl("qrc:/main.qml"));
    view.show();
    return app.exec();
}
main.qml
import QtQuick 2.4
import Pixel 1.0
import QtQuick.Controls 1.2

Item {
    width: 1020
    height: 1020

    Flickable {
        anchors.fill: parent
        contentWidth: 1000; contentHeight: 1000
        PixelGrid {
            id: pixelGrid
            anchors { fill: parent; margins: 10 }
        }

    }
    Slider {
        anchors { bottom: parent.bottom; bottomMargin: 20;
            horizontalCenter: parent.horizontalCenter }
        minimumValue: 1
        maximumValue: 100
        value: 100
        onValueChanged: pixelGrid.scale = value / 100
    }
}

fluorite ★★★★★
()
Ответ на: комментарий от fluorite

Это реально круто!!!

Просто невероятно, на 5000x5000 клеток без тормозов!

Только я вот уже в сторону оптимизации думаю. 10Gb ram не каждый комп осилит...

Придется думаю сделать как ранее предлагали: рендерится поле, а за тем в нужных местах создаются rect'ы на заказ.

deterok ★★★★★
() автор топика
Ответ на: комментарий от fluorite

Кстати, пытался разобраться здесь в вашем коде и немного не понял как оно работает, не мог ли бы вы рассказать?

deterok ★★★★★
() автор топика
Ответ на: комментарий от CrossFire

Такой вопросик возник.

Вот я накидал итем на QtQuickPaintedItem, он по сути является view'ером табличных моделей, но без скролинга и масштабирования, сделал ему проперти различные и накидал небольшой компонент на QML с drag'ингом зумом и т.д. Теперь возник вопрос в архитектуре приложения...

Вот есть у меня интерфейс на QML + C++. Я хочу использовать свою модель и написал функцию на C++. Для вызова из QML-GUI я должен ее пометить как Q_INVOCABLE (ну или что-то типа того). Но не тут-то было! Она должна быть методом QObject... И я тут если честно в замешательстве... Т.е. мне очень хочется писать на чистом C++, но одновременно сохранить QML интерфейс и все такое, т.к. планирую поддержку Android.

Как быть в такой ситуации?

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Если хотим использовать Qt — от QObject никуда не деться.

CrossFire ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.