如何在单个App中混合使用Qt和原生iOS用户界面元素?

我正在使用Qt 5.2 for iOS.

我想在单个应用程序中将QtQuick 1.1或QWidgets与本机iOS用户界面元素混合使用.

将qml视图嵌入到UIView中,必须切换到另一个窗口,将UIView嵌入到qml组件中,欢迎任何帮助!

最佳答案 有点晚了,可以在Qt宇宙上显示原生UIView.

嵌入UIView的技术是让UIView“浮动”在层次结构中的QWidget上,并在层次结构小部件的几何变化时更新UIView的几何.对此的限制:您不能简单地将这样的小部件放在QTabWidget中(然后您需要额外的代码来隐藏/显示UIView).同样QMain
Windows在包含UIView的QMainWindow上升也无效.

class View : public QWidget
  ...
  private:
    UITextView* m_TextView;
    bool m_scheduled;

履行

View::View(QWidget* parent):QWidget(parent),m_Scheduled(false)
{
    m_TextView=[[UITextView alloc] init];
    QWidget* w= window();
    UIView *parentView = reinterpret_cast<UIView *>(w->winId());
    [parentView addSubview:m_TextView];
}
View::~View()
{
    [m_TextView removeFromSuperview];
    m_TextView=nil;
}
bool View::event(QEvent* e)
{
    if (e->type()==QEvent::Move || e->type()==QEvent::Resize) {
      if (!m_scheduled) {
        m_scheduled=true;
        QTimer::singleShot( 0, this, SLOT( updateGeo() ) );
      }
    }
    return QWidget::event(e);
}
static inline QRect globalRect(QWidget* widget)
{
    return QRect((widget)->mapToGlobal(QPoint(0,0)), (widget)->size());
}
void View::updateGeo()
{
    m_scheduled=false;
    QRect rg=globalRect(this);
    QRect rw=globalRect(window());
    CGRect cg=CGRectMake(rg.x(), rg.y()-rw.y(), rg.width(), rg.height());
    [m_TextView setFrame:cg];
}

完整的示例项目可以找到here.
另一种方法是使用QML查看器和qmlRegisterType来注册QQuickItem后代.

qmlRegisterType<MyTextView>("MyTextView", 1, 0, "MyTextView");

class MyTextView : public QQuickItem
   ...
   private:UITextView* m_view;

在实现中,overrideChanged方法被覆盖以计算UIView坐标中的新矩形

static inline CGRect toCGRect(const QRectF &rect)
{
  return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
}
MyTextView::MyTextView(QQuickItem *parent /*= 0*/)
    : QQuickItem(parent)
    , m_view(0)
{
    connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(onWindowChanged(QQuickWindow*)));
    connect(this, SIGNAL(visibleChanged()), this, SLOT(onVisibleChanged()));
}

MyTextView::~MyTextView()
{
    [m_view release];
}
void MyTextView::onWindowChanged(QQuickWindow* window)
{
    if(!m_view) {
        m_view = [[UITextView alloc] init];
    }
    if (window != 0) {
        UIView *parentView = reinterpret_cast<UIView *>(window->winId());
        [parentView addSubview:m_view];
    } else {
        [m_view removeFromSuperView];
    }
}
void MyTextView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    QQuickItem::geometryChanged(newGeometry, oldGeometry);
    CGRect rc = toCGRect(mapRectToScene(newGeometry).toRect());
    rc.size.width -= 2;
    rc.size.height -= 2;
    [m_view setFrame:rc];
}
void MyTextView::onVisibleChanged()
{
    [m_view setHidden:isVisible()];
}

并在qml文件中

...
import MyTextView 1.0

Window {
    visible: true

    Column {
        anchors.fill: parent
        anchors.margins: 5
        spacing: 5

        Rectangle {
            anchors.left: parent.left
            anchors.right: parent.right
            height: 100
            border.width: 1
            border.color: "red"
            color: "#cccccc"

            MyTextView {
                anchors.fill: parent
                anchors.margins: 1
            }
        }
    }
}

完整的样本项目可以在here找到.

点赞