2014-10-11 116 views
2

我开始用QML编写应用程序(使用QtQuick 1.1和Qt 4.8.1),我有几个关于信号的问题。在我的项目有以下文件:QML信号连接

main.qml:

Rectangle { 
    signal sigExit() 
    width: 800 
    height: 600 
    Text { 
     text: qsTr("Hello World") 
     anchors.centerIn: parent 
    } 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      sigExit(); 
      Qt.quit(); 
     } 
    } 
    Button 
    { 
     x: 10 
     y: parent.height-height-5 
     text: "someText" 
    } 
} 

Button.qml:

Rectangle { 
    signal buttonsig() 
    width: 60 
    //(...) 
    MouseArea 
    { 
     anchors.fill: parent 
     onClicked: buttonsig(); 
    } 
} 

当我想从信号连接main.qml到C++插槽,我做的:

main.cpp:

QmlApplicationViewer viewer; 
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); 
viewer.setMainQmlFile(QLatin1String("qml/MyProject/main.qml")); 
viewer.showExpanded(); 

MyClass* obj = new MyClass; 
QObject* item = qobject_cast<QObject*>(viewer.rootObject()); 
QObject::connect(item, SIGNAL(sigExit()), obj, SLOT(onExitWindow())); 

它工作。但是当我想将sigbutton()Button.qml连接到C++插槽时怎么办?它会是这样的?

QObject *rect = item->findChild<QObject*>("Button"); 
QObject::connect(rect, SIGNAL(buttonsig()), obj, SLOT(onExitWindow())); 

而第二个问题:我如何连接到sigbutton()main.qml(例如,我想他们点击后,改变我的按钮的位置)?

回答

1

您还需要有你Button项目的objectName财产,如果你想访问:

Button { 
    id: myButton 
    objectName: "myButton" 
    x: 10 
    y: parent.height-height-5 
    text: "someText" 
} 

现在,您可以通过访问:

QObject *rect = item->findChild<QObject*>("myButton"); 

关于第二个问题,您可以使用Connections对象将buttonsig()连接到main.qml中的某些QML信号处理程序:

Rectangle { 
    signal sigExit() 
    width: 800 
    height: 600 

    Connections{ 
     target: myButton 
     onButtonsig : 
     { 
      ... 
     } 
    } 

    Text { 
     text: qsTr("Hello World") 
     anchors.centerIn: parent 
    } 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      sigExit(); 
      Qt.quit(); 
     } 
    } 
    Button 
    { 
     id: myButton 

     x: 10 
     y: parent.height-height-5 
     text: "someText" 
    } 
} 

请注意,信号处理程序的名称应该是on<Signal>(信号首字母大写)。 Button也应该有一个id来解决它在Connections

+0

谢谢!那么第二个问题呢?是否有可能将信号从一个QML文件连接到另一个QML文件中的插槽(或类似的东西)? – trivelt 2014-10-11 11:49:54

1

访问已加载的qml元素,转换它们并将它们的信号连接到C++插槽是非常可能的。但是在生产代码中应该避免使用这种方法。 See this warning from Qt docs.

那么从qml端调用C++插槽有什么方法?您可以使用qml引擎将需要调用插槽的对象注册为上下文属性。一旦注册,这些上下文属性就可以从QML的任何地方访问。注册为背景属性的对象

插槽可以直接在信号处理程序QML example: onClicked:{<contextPropertyName>.<slotName>()}

被称为或者,你可以连接与上下文属性对象的插槽直接使用Connections类型QML信号。请参阅this documentation

有关注册上下文属性的详细信息,请参阅Embedding C++ objects into QML with context properties.

如果你想看到一些例子,看看我这些问题的答案。 Qt Signals and Slots - nothing happensSetting object type property in QML from C++