【问题标题】:Reuse qt c++ widgets in qml在 qml 中重用 qt c++ 小部件
【发布时间】:2017-03-27 10:36:59
【问题描述】:

我打算用 QML 创建一个应用程序。 我在 C++ 中实现了很多 qt 小部件。 c++ 小部件应该在 QML 中使用。

如何整合它们? - dll的路径 - 是否存在一些 qml 容器?

我没有找到解决这个问题的好文档

【问题讨论】:

标签: qml qtwidgets


【解决方案1】:

这是可能的,但不是可取的,除非有问题的小部件有很多图形(如果你有一个基于 QGraphivsView 的类)。如果您所指的小部件是“普通”的 QWidget,请不要尝试这样做,因为它比它的价值更麻烦。

您需要创建一个继承 QQuickPaintedItem 并覆盖一些方法的新类:

标题:

class QQmlWidget : public QQuickPaintedItem
{
    Q_OBJECT    
public:
    explicit QMLProfile(QWidget *internalWidget, QQuickItem *parent = 0) : QQuickPaintedItem(parent), internalWidget(internalWidget){}
    virtual ~QMLProfile();
    void paint(QPainter *painter) override;

protected:
    void mouseMoveEvent(QMouseEvent *event);
private:
    QWidget *internalWidget;
};

Cpp: (以下代码来自 Subsurface 代码,在 QML 上使用 QGraphivsView)

void paint(QPainter* painter) {
    // let's look at the intended size of the content and scale our scene accordingly
    QRect painterRect = painter->viewport();
    QRect profileRect = internalWidget->viewport()->rect();

    qreal sceneSize = 104; // that should give us 2% margin all around (100x100 scene)
    qreal dprComp =  devicePixelRatio() * painterRect.width() / profileRect.width();
    qreal sx = painterRect.width() / sceneSize / dprComp;
    qreal sy = painterRect.height() / sceneSize / dprComp;

    // next figure out the weird magic by which we need to shift the painter so the widget is shown
    int dpr = rint(devicePixelRatio());
    qreal magicShiftFactor = (dpr == 2 ? 0.25 : (dpr == 3 ? 0.33 : 0.0));

    // now set up the transformations scale the profile and
    // shift the painter (taking its existing transformation into account)
    QTransform profileTransform = QTransform();
    profileTransform.scale(sx, sy);
    QTransform painterTransform = painter->transform();
    painterTransform.translate(-painterRect.width() * magicShiftFactor ,-painterRect.height() * magicShiftFactor);

    // apply the transformation
    painter->setTransform(painterTransform);
    internalWidget->setTransform(profileTransform);

    // finally, render the profile
    internalWidget->render(painter);
}

QQmlWidget::mouseMoveEvent(QMouseEvent *ev){
     /* Map the eveent to the Widget */
     QQuickPaintedItem(ev);
     internalWidget->mouseEvent(ev);
}

正如我所说,可行,但不是很直截了当。仅当您无法在 QML 中重新创建小部件时才这样做。

【讨论】:

  • 您没有解决鼠标和键盘输入问题。
  • 我的特殊情况是我不需要处理鼠标输入或键盘,因为我想要的只是生成一个静态图像,对于鼠标和键盘交互,您需要做的就是按照我的方式映射事件'v 在评论代码中说。
  • 有很多鼠标和键盘输入,就像一个完整的编辑器,有很多业务逻辑的表格视图......
  • 如果您的自定义绘图、事件处理和逻辑与QWidget 容器足够分离,那么您可以直接在QQuickPaintedItem 中使用它们。如果您的小部件没有委托而是直接在其类中实现所有内容,那么像此答案中描述的代理方法可能比尝试分离更容易。
猜你喜欢
  • 2015-02-10
  • 2018-06-19
  • 1970-01-01
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多