美文网首页
QT - 信号和事件处理系统

QT - 信号和事件处理系统

作者: YottaYuan | 来源:发表于2020-04-16 05:02 被阅读0次

    QT - 信号和事件处理系统

    应用程序和用户界面组件需要相互通信。例如,一个按钮需要知道用户已单击它。该按钮可以更改颜色以指示其状态或执行某些逻辑。同样,应用程序需要知道用户是否正在单击按钮。应用程序可能需要将此点击事件中继到其他应用程序。

    QML具有信号和信号处理机制,其中信号是事件,信号通过信号处理程序进行响应。发出信号时,将调用相应的信号处理程序。在处理程序中放置诸如脚本或其他操作之类的逻辑,使组件可以响应事件。

    使用信号处理程序接收信号

    为了在特定对象发出特定信号时接收通知,对象定义应声明一个名为on<Signal>的信号处理程序,其中<Signal>信号的名称,首字母大写。信号处理程序应包含在调用信号处理程序时要执行的JavaScript代码。

    例如,来自Qt Quick Controls模块的Button类型具有一个信号,该信号在单击按钮时发出。在这种情况下,用于接收此信号的信号处理程序应为onClicked。在下面的示例中,每当单击按钮时,都会调用处理程序,并为父Rectangle应用随机颜色:

      import  QtQuick  2.14
      import  QtQuick.Controls  2.14
      Rectangle  {
          id:  rect
          width:  250;  height:  250
          Button  {
              anchors.bottom:  parent.bottom
              anchors.horizontalCenter:  parent.horizontalCenter
              text:  "Change color!"
              onClicked:  {
                  rect.color  =  Qt.rgba(Math.random(),  Math.random(),  Math.random(),  1);
              }
          }
      }
    

    属性更改信号处理程序

    QML属性的值更改时,会自动发出信号。此类信号是属性更改信号,这些信号的信号处理程序以on<Property>Changed的形式编写,其中<Property>属性的名称,首字母大写。

    例如,鼠标区域类型具有按下Pressed特性。要在此属性更改时接收通知,请编写名为onPressedChanged的信号处理程序:

        import  QtQuick  2.14
    
        Rectangle  {
          id:  rect  width:  100;  height:  100
          TapHandler  {
              onPressedChanged:  console.log("taphandler pressed?",  pressed)
          }
      }
    

    尽管TapHandler文档中没有记录名为的信号处理程序onPressedChanged,该信号还是由该pressed属性存在的事实隐式提供的。

    使用连接(Connections)类型

    在某些情况下,可能希望访问发出该信号的对象之外的信号。为此,QtQuick模块提供用于连接任意对象信号的Connections类型。该连接对象可以接收来自它的指定的任何信号的目标

    例如,onClicked在前面的示例中的处理程序可能已被由所述根接收矩形代替,通过将onClicked处理程序在一个连接具有其对象目标集到button

        import  QtQuick  2.14
        import  QtQuick.Controls  2.14
        Rectangle  {  id:  rect  width:  250;  height:  250
    
        Button  {
          id:  button
          anchors.bottom:  parent.bottom
          anchors.horizontalCenter:  parent.horizontalCenter
          text:  "Change color!"
      }
    
      Connections  {
          target:  button
          onClicked:  {
              rect.color  =  Qt.rgba(Math.random(),  Math.random(),  Math.random(),  1);
          }
        }
      }
    
    

    附加信号处理程序

    一个附加的信号处理程序,从一个接收信号附加类型,而不是在其内的处理程序被声明的对象。

    例如,Component.onCompleted是一个附加的信号处理程序。创建过程完成后,通常用于执行一些JavaScript代码。示例如下:

      import  QtQuick  2.14
    
      Rectangle  {
          width:  200;  height:  200
          color:  Qt.rgba(Qt.random(),  Qt.random(),  Qt.random(),  1)
    
          Component.onCompleted:  {
              console.log("The rectangle's color is",  color)
          }
      }
    

    onCompleted处理程序没有响应于completed从信号矩形类型。而是,带有信号的Component 附加类型的对象已由QML引擎completed自动附加Rectangle对象。创建Rectangle对象时,引擎会发出此信号,从而触发Component.onCompleted信号处理程序。

    附加的信号处理程序允许将对每个单独对象重要的特定信号通知给对象。Component.onCompleted例如,如果没有附加的信号处理程序,则一个对象如果不从某个特殊对象注册某些特殊信号就无法接收该通知。所述附接的信号处理程序机制使得对象以接收特定的信号而无需额外的代码。

    有关附加信号处理程序的更多信息,请参见附加属性和附加信号处理程序。

    向自定义QML类型添加信号

    可以通过signal关键字将信号添加到自定义QML类型。

    定义新信号的语法为:

    signal <name>[([<type> <parameter name>[, ...]])]

    通过调用信号作为一种方法来发出信号。

    例如,以下代码在名为的文件中定义SquareButton.qml。根矩形对象具有一个activated信号,每当子被发射TapHandlertapped。在此特定示例中,激活的信号以鼠标单击的x和y坐标发出:

      // SquareButton.qml
      import  QtQuick  2.14
      Rectangle  {
          id:  root
          signal activated(real xPosition, real yPosition)
          property  point  mouseXY
          property  int  side:  100
          width:  side;  height:  side
    
          TapHandler  {
              id:  handler
              onTapped:  root.activated(mouseXY.x,  mouseXY.y)
              onPressedChanged:  mouseXY  =  handler.point.position
          }
      }
    

    现在,任何对象都SquareButton可以activated使用onActivated信号处理程序连接到信号:

    // myapplication.qml
    SquareButton {
        onActivated: console.log("Activated at " + xPosition + "," + yPosition)
    }
    

    有关为自定义QML类型编写信号的更多详细信息,请参见信号属性

    将信号连接到方法和信号

    信号对象具有connect()将信号连接到方法或另一个信号的方法。当信号连接到方法时,只要发出信号,该方法就会自动调用。这种机制使信号可以通过方法而不是信号处理程序来接收。

    下面,messageReceived使用该connect()方法将信号连接到三种方法:

      import  QtQuick  2.14
      Rectangle  {
          id:  relay
          signal messageReceived(string person,  string notice)
    
          Component.onCompleted:  {
              relay.messageReceived.connect(sendToPost)
              relay.messageReceived.connect(sendToTelegraph)
              relay.messageReceived.connect(sendToEmail)
              relay.messageReceived("Tom",  "Happy Birthday")
          }
    
          function  sendToPost(person, notice)  {
              console.log("Sending to post: "  +  person  +  ", "  +  notice)
          }
          function  sendToTelegraph(person, notice)  {
              console.log("Sending to telegraph: "  +  person  +  ", "  +  notice)
          }
          function  sendToEmail(person, notice)  {
              console.log("Sending to email: "  +  person  +  ", "  +  notice)
          }
      }
    

    在许多情况下,通过信号处理程序接收信号而不是使用connect()函数就足够了。但是,使用该connect方法可以通过多种方法接收信号,如前所述,这对于信号处理程序来说是不可能的,因为它们必须唯一地命名。同样,该connect方法在将信号连接到动态创建的对象时很有用。

    disconnect()消除连接信号的相应方法:

      Rectangle  {
          id:  relay
          //...
          function  removeTelegraphSignal()  {
              relay.messageReceived.disconnect(sendToTelegraph)
          }
      }
    

    信号对信号连接

    通过将信号连接到其他信号,该connect()方法可以形成不同的信号链。

      import  QtQuick  2.14
    
      Rectangle  {
          id:  forwarder
          width:  100;  height:  100
    
         signal send()
         onSend:  console.log("Send clicked")
    
         TapHandler  {
          id:  mousearea
          anchors.fill:  parent
          onTapped:  console.log("Mouse clicked")
        }
        Component.onCompleted:  {
          mousearea.tapped.connect(send)
        }
      }
    

    每当发射TapHandlertapped信号时,该send信号也会自动发射。

    output:
        MouseArea clicked
        Send clicked
    

    相关文章

      网友评论

          本文标题:QT - 信号和事件处理系统

          本文链接:https://www.haomeiwen.com/subject/jqwymhtx.html