2012-10-22 32 views
26

Tôi đang sử dụng bản beta Qt5 và cố gắng nhúng đối tượng dựa trên QWidget vào QML. Mục đích là sử dụng QML càng nhiều càng tốt, và chỉ sử dụng các đối tượng QWidget mà QML không làm những gì tôi cần. Tôi tìm thấy một liên kết giải thích làm thế nào để làm điều này cho Qt4.7, nhưng tôi đã không tìm thấy bất kỳ thông tin giải thích làm thế nào để làm điều này trong Qt5.Qt5. Nhúng đối tượng QWidget vào QML

http://doc.qt.digia.com/4.7/declarative-cppextensions-qwidgets.html

Các ví dụ tương tự cũng có sẵn trong các ví dụ Qt5 thư mục dưới:

ví dụ \ qtquick1 \ declarative \ cppextensions \ qwidgets

Thật không may, ví dụ này sử dụng QtQuick 1, chứ không phải là QtQuick 2, và tôi muốn sử dụng các tính năng mới của Qt5. Tôi thực sự muốn nhúng một widget qwt, nhưng như một bước đầu tiên tôi sẽ rất vui khi nhúng bất kỳ đối tượng QWidget đơn giản nào.

Ai đó có thể giúp tôi lấy ví dụ làm việc theo Qt5/QtQuick 2 không?

+2

Một số tin tức liên quan về vấn đề này: [QtQuickWidget] (https://qt.gitorious.org/qt/qtdeclarative/source/b02bed1caae6966925b9efb04e1db79c3e9ef687:src/quickwidgets/qquickwidget.cpp#L169) giải quyết được vấn đề này; có nghĩa là, nhúng các mục Qt Quick vào các tiện ích. Nó sẽ có sẵn trong Qt 5.3. – Mitch

Trả lời

32

Qt Quick 2 sử dụng biểu đồ cảnh để hiển thị hiệu quả trên GPU. Thật không may điều này làm cho nó không thể nhúng vật dụng cổ điển vào hiện trường. Cách tiếp cận cũ để nhúng các vật dụng như vậy với sự giúp đỡ của QGraphicsProxyWidget chỉ hoạt động với Qt Quick 1, bởi vì nội bộ nó sử dụng một QGraphicsView cho tất cả các nâng nặng và QGraphicsProxyWidget có nghĩa là để được sử dụng với nó.

Hiện tại không có kế hoạch cho phép nhúng QWidgets cổ điển vào biểu đồ cảnh mà tôi biết. Tôi nghĩ rằng điều này là khá khó thay đổi, bởi vì các khái niệm về QPainter, khung vẽ được sử dụng cho các widget cổ điển và biểu đồ cảnh mới không chơi tốt với nhau.

Có một số nỗ lực để phát triển các bộ tiện ích mới được thiết kế riêng cho nhu cầu của QML, nhưng không có công cụ nào mạnh mẽ và trưởng thành như các tiện ích cổ điển. Những cái nổi bật nhất là QML Quick Controls, đi kèm với Qt kể từ phiên bản 5.1.

Nếu bạn thực sự phụ thuộc vào QWT, lời khuyên của tôi sẽ là gắn liền với Qt Quick 1.1 ngay bây giờ. Nó vẫn được đóng gói với Qt 5, có thể cho các trường hợp như của bạn. Bằng cách đó, bạn sẽ không tận dụng lợi thế của đồ thị cảnh mới.

+0

Cảm ơn bạn đã giải thích rất rõ ràng. Dự án của tôi vẫn còn đủ mới mà tôi không hoàn toàn cam kết với QWT. – eatyourgreens

+4

Cập nhật: Các tiện ích QML tinh khiết còn gọi là thành phần đã trưởng thành rất nhiều kể từ khi câu trả lời này được đăng. –

6

Điều gì có thể làm là hiển thị tiện ích cho hình ảnh và tải lên dưới dạng kết cấu. Đối với tương tác, ai đó cần chuyển tiếp các sự kiện như mouseClick hoặc keyPressed từ sceneGraph, dịch sang tọa độ tiện ích, truyền lại, kết xuất và tải lên lại. Chỉ cần một ý tưởng :)

+6

Chính xác. Nhưng cách tiếp cận này đòi hỏi một cá nhân sáng tạo và táo bạo. – user1095108

6

Cách tiếp cận được khuyến nghị là ở lại với ứng dụng dựa trên QWidget và nhúng các phần QML bằng cách sử dụng QWidget :: createWindowContainer.

2

Bạn có thể nhúng QWidget để QML bằng cách sử dụng lớp QQuickPaintedItem: http://doc.qt.io/qt-5/qquickpainteditem.html

Qt5 có một ví dụ: http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html

Bạn nên thực hiện một cố hữu của QQuickPaintedItem với thuộc tính phụ tùng tư nhân, mà bạn muốn nhúng. Cung cấp phương thức vẽ, chỉ hiển thị QtWidget và cung cấp chuột và sự kiện truyền khác từ kế thừa QQuickPaintedItem để nhúng QtWidget.

Ngoài ra còn có QSG (API đồ thị cảnh Qt), nhưng trải nghiệm của tôi với điều đó không được mượt mà. Tôi tin rằng đầu mối trong đa luồng (thực hiện rendering trong thread khác nhau (không phải là Qt GUI thread một, tuy nhiên trên Windows đó là không đúng sự thật và tất cả được thực hiện trong thread GUI chính).

Tôi đã thực hiện nhúng của QCustomPlot, đây là liên kết: github.com/mosolovsa/qmlplot

0

Tiếp tục câu trả lời Julien - một cách đơn giản để đạt được điều này là sử dụng QQuickWidget để hiển thị các cảnh QML, và sau đó thêm một QWidget bình thường như một đứa trẻ của QQuickWidget. Bạn cũng có thể thêm QObject trung gian đơn giản để gắn QWidget vào một mục trong cảnh.

Ví dụ:

Trong main.qml:

Item { 

    ... // layouts, extra items, what have you 

     Item 
     { 
      objectName: "layoutItem" 
      anchors.fill: parent 
     } 

    ... // more layouts, extra items, etc. 
} 

widgetanchor.h:

class WidgetAnchor: public QObject 
{ 
    ptr<QWidget> _pWidget; 
    QPointer<QQuickItem> _pQuickItem; 
public: 
    WidgetAnchor(QWidget* pWidget, QQuickItem* pItem) 
     : QObject(pWidget), _pWidget(pWidget), _pQuickItem(pItem) 
    { 
     connect(_pQuickItem, &QQuickItem::xChanged, this, &WidgetAnchor::updateGeometry); 
     connect(_pQuickItem, &QQuickItem::yChanged, this, &WidgetAnchor::updateGeometry); 
     connect(_pQuickItem, &QQuickItem::widthChanged, this, &WidgetAnchor::updateGeometry); 
     connect(_pQuickItem, &QQuickItem::heightChanged, this, &WidgetAnchor::updateGeometry); 
     updateGeometry(); 
    } 
private: 
    void updateGeometry() 
    { 
     if (_pQuickItem) 
     { 
      QRectF r = _pQuickItem->mapRectToItem(0, QRectF(_pQuickItem->x(), _pQuickItem->y(), _pQuickItem->width(), _pQuickItem->height())); 
      _pWidget->setGeometry(r.toRect()); 
     } 
    } 
}; 

Trong main.cpp:

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

    auto pqw = new QQuickWidget; 
    pqw->setSource(QUrl::fromLocalFile("main.qml")); 
    pqw->setResizeMode(QQuickWidget::SizeRootObjectToView); 
    pqw->setAttribute(Qt::WA_DeleteOnClose); 
    auto pOwt = new MyWidget(pqw); 
    if (auto pOverlayItem = pqw->rootObject()->findChild<QQuickItem*>("overlayItem")) 
     new WidgetAnchor(pOwt, pOverlayItem); 
    pqw->show(); 

    return app.exec(); 
} 

Các tài liệu nói rằng sử dụng QQuickWidget có quảng cáo vantages trên QQuickView và QWidget :: createWindowContainer, chẳng hạn như không có hạn chế về thứ tự xếp chồng, nhưng có một 'hiệu suất nhỏ hit'.

Hy vọng điều đó sẽ hữu ích.

0

Here giải thích cách thêm QComboBox trên bố cục dựa trên QML. Hãy nghĩ rằng ví dụ tốt cho trường hợp của bạn. (Trong Qt 5.9 đã thực hiện điều khiển ComboBox QML gốc).

+0

Lưu ý rằng điều này giải thích cách nhúng trong Qt Quick 1, không phải Qt Quick 2. – fkorsa