2016-08-31 2 views
7

타일로 채워진 거대한 직사각형 격자를 상상해보십시오. 개별 타일은별로 복잡하지 않으며, 모양이 적은 svg 이미지입니다.QML에서 거대한 타일을 처리하는 방법은 무엇입니까?

크기가 매우 큰 타일의 종류가 많지 않으므로 수백 가지로 추정합니다. 그러나 그리드가 매우 커질 수 있으므로 총 타일 수는 매우 많습니다 (최소 수만 개 이상).

가로 및 세로로 그리드를 부드럽게 스크롤 할 수 있어야하고 부드럽게 확대/축소 할 수 있어야합니다. 나는 또한 특정 위치로 이동할 수 있어야합니다.

비동기 적으로 채울 수 있다면 처음에는 실제로 볼 수있는 요소를 만들고 나머지는 나머지 요소를 채울 수 있으면 좋을 것입니다. 즉, 시작 위치가 반드시 왼쪽 상단이 아니기 때문에 루프에서 행과 열을 먼저 추가해야하는 테이블 처리 클래스가 최적의 솔루션이 아님을 의미합니다.

확대/축소는 배율 인수의 배수로 지정된 타일 내의 항목의 모든 속성을 widthheight 개로 간단하게 설정합니다. svg은 다른 이미지 수가 많지 않으므로 문제가되지 않아야하며 캐시 할 수 있어야합니다. 드물게 svg이 병목 현상이 된 경우 다른 해상도의 다른 png 세트를 사용할 수 있습니다.

I 시도 (또는 생각) 다음 방법 다음 SameGame example의 방법을 사용

  1. , QML 만들기 (Component.createObject) 동적 객체. 이것은 객체의 수가 적지 만 많은 객체가있는 경우 매우 느립니다. 개체가 완전히 비어있는 경우에도이 메서드는 very long time이됩니다.

  2. Flickable 안에 Repeater을 사용합니다. Flickable에는 Grid이 포함되어 있으며 Repater으로 채워집니다. 물론 Grid은 엄청납니다. 이 방법은 객체를 동적으로 생성하는 것보다 빠르지 만 타일 수가 늘어 나면 여전히 비효율적입니다. QML 엔진은 보이지 않는 항목까지도 모든 항목을 추적합니다. 확대/축소는 또한 눈에 보이는 것뿐만 아니라 모든 항목의 속성이 다시 계산되므로 매우 느립니다.

  3. GridView을 사용한다. 이것은 첫눈에 완벽한 솔루션처럼 보입니다. GridViewFlickable을 상속하며보기 경계 내에있는 내용 만 렌더링해도됩니다. 수백만 개의 svg 이미지가있는 테스트 케이스조차도 비교적 빨리 실행되며 스크롤하고 크기를 부드럽게 조정합니다. 단 하나의 문제가 있습니다 : GridView은 수평 또는 수직으로 가볍게 쓸어 넘길 수 있지만 둘 다만 쓸 수는 없습니다. 2012 년 이래 약 feature request가 있었지만 여전히 무시당하는 것으로 보입니다.

  4. QGraphicsView을 직접 사용하십시오. 필요한 요소를 표시, 스크롤 및 확대/축소하는 것은 is capable이지만 QML 기반이 아닙니다. 나머지 GUI는 QML로되어 있으며, QMLQGraphicsView을 결합하는 것에 대한 공포 이야기 만 읽었습니다. 나는 그 어떤 합리적인 예도 본 적이 없다.

다른 해결책이 있습니까?Flickable으로 이동하는 동안 단순한 GridLayout (행과 열이 보이는 영역보다 크다)의 행과 열을 추가하고 제거하기 위해 Javascript를 사용하는 몇 가지 끔찍한 해킹이 있습니까? 또는 OpenGL 창을 포함시키고 모든 것을 수동으로 그립니까?

나는 이것이 불가능한 작업이 아니길 바란다. 20 년 전 DOS와 Windows 95 용으로 작성된 전략 게임이 텍스쳐와 애니메이션을 추가적으로 가지고 있지만이 정도의 타일을 처리 할 수있었습니다.

+1

DOS와 Windows 95의 비교는 기본 기술과 접근 방식이 매우 다르므로 의미가 없습니다. 필요한 것을 수행하는 커스텀 QtQuick 엘리먼트를 사용하지 않는 이유는 무엇입니까? – peppe

+0

@peppe : 요점은 시스템 자체가 아니었지만 200 배 적은 계산 능력으로 가능하다는 것이 었습니다. 그리고 "custom QtQuick element"에 의해 제 2D 그래픽 엔진을 처음부터 구현해야한다는 것을 의미합니까? 가능 합니다만, 그 방법은 OpenGL 그리기 솔루션과 유사합니다. 'GridView'는로드 할 때와 언로드 할 때를 언제 어디서 알 수 있다는 장점이 있습니다. 처음부터 모든 것을함으로써 모든 메모리 관리, 가시성 계산, 모든 것을 구현해야합니다. 처음부터 모든 것을 구현해야한다면 Qt를 사용해야하는 이유는 무엇입니까? – vsz

+1

오늘까지도 완전히 할 수 있지만 10000 개의 요소가있는 리피터는 잘못된 접근입니다. QML에 이러한 기본 제공 기능이 없다는 사실이 실현 불가능하다는 것을 의미하지는 않습니다. – peppe

답변

1

그래, Qt는 매우 유용하고 중요하다고 생각되며 zip support과 같이 가장 많이 투표 한 사람 일지라도 수년간 커뮤니티 제안을 무시하는 데 매우 좋습니다.

저는 개인적으로 "수정"GridView을 신경 쓸 필요가 없지만, C++을 사용하여보다 빠르고 효율적으로 제 특정 요구 사항에 맞는 무언가를 구현합니다. 타일이 균일 한 정사각형이라면 매우 쉽습니다. 내부의 실제 이미지가 정사각형이 아닐지라도, 그 타일을 벗어날 수있는 것처럼 들립니다. 이렇게하면 프로그래밍 방식으로 위치를 쉽게 결정할 수있을뿐만 아니라 왼쪽 상단 모서리, 한 줄당 타일 수 및 후속 선의 보폭을 결정할 수 있습니다. 그런 다음 가시성 사각형이 이동함에 따라 컨테이너와 신호를 반복하여 가시성을 입력하는 요소에 대한 QML 요소를 만듭니다. 쉬워요.

아무 것도 필요 없으며 QObject을 상속하고, 유형을 QML에 등록한 다음 이동하여 내부 "모델"로 채 웁니다. 당신은 분명히 메모리에 모든 객체를 갖고 싶지 않습니다. 장면 그래프가 렌더링되지 않을 정도로 똑똑하더라도, 여전히 처리 할 것입니다. FPS에서의 드롭은 GPU의 제품이 아니라 CPU 병목 현상입니다. .

실제 그리드 객체는 데이터가 Q_SIGNAL void create(x, y, imgPath); 인 생성 및 파괴 신호를 방출 할 수 있으므로 QML 측에서 사용자 정의 핸들러를 바인딩하면 "위임"객체를 쉽게 지정할 수있는 등의 유연성과 사용 편의성을 제공합니다. C++에서 실제 생성/제거를 수행하는 것보다 더 우아 할 것입니다. QML 측면에서 바인딩을 사용하면 화면에서 벗어나 자급 자족 할 때 추적 할 수있는 몇 가지 항목을 사용할 수 있습니다. 이렇게하면 모든 "살아있는"객체를 추적 할 필요가 없기 때문에 복잡성을 최소화 할 수 있습니다.

Component { 
    id: objComponent 
    Image { 
     property bool isVisible: { is in grid.visibleRect ??? } 
     onIsVisibleChanged: if (!isVisible) destroy() 
    } 
} 

MyGrid { 
    id: grid 
    contentX: flickable.contentX 
    contentY: flickable.contentY 

    onCreate: objComponent.createObject(flickable.contentItem, {"x" : x, "y" : y, "source" : imgPath}) 
} 

Flickable { 
    id: flickable 
    contentWidth: grid.contentWidth 
    contentHeight: grid.contentHeight 
} 

일반적으로, 사용자가 내가 코드를 작업 만들어 줄 현상금을 제공 할만큼 중요한 질문을 가지고 있지만, 불행히도 나는 현재 너무 바빠서 때. 개념은 꽤 간단하지만 구현하기에 너무 문제가 있어서는 안됩니다.

+2

GridView *는 C++로 구현되었습니다. –

+0

@ DavidK.Hess - 또한 누가 주장하지 않습니까? – dtech

관련 문제