Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Qt共享库和Qt应用程序之间使用信号和插槽_Qt_Shared Libraries - Fatal编程技术网

在Qt共享库和Qt应用程序之间使用信号和插槽

在Qt共享库和Qt应用程序之间使用信号和插槽,qt,shared-libraries,Qt,Shared Libraries,我有一个工作示例,它使用信号和插槽在Qt共享库(dll)和Qt应用程序之间进行通信。我的问题是,这是首选方法还是有更好的方法来处理qt共享库。详情如下: 我开发的应用程序具有监听网络上的设备和更新GUI的功能。共享库负责监听网络上的设备,Qt应用程序模块负责GUI部分 我有一个宏,它使用Q_DECL_EXPORT/Q_DECL_IMPORT导出共享库和应用程序使用的公共类。这个公共类派生自QObject,定义了Qt信号和插槽。这个公共类是作为共享库(dll)的一部分构建的 Qt应用程序在编译时加

我有一个工作示例,它使用信号和插槽在Qt共享库(dll)和Qt应用程序之间进行通信。我的问题是,这是首选方法还是有更好的方法来处理qt共享库。详情如下:

我开发的应用程序具有监听网络上的设备和更新GUI的功能。共享库负责监听网络上的设备,Qt应用程序模块负责GUI部分

我有一个宏,它使用Q_DECL_EXPORT/Q_DECL_IMPORT导出共享库和应用程序使用的公共类。这个公共类派生自QObject,定义了Qt信号和插槽。这个公共类是作为共享库(dll)的一部分构建的

Qt应用程序在编译时加载共享库,并为公共类创建实例,并使用该实例在Qt应用程序和Qt共享库模块之间设置信号和插槽,如下所示:

在Qt应用程序初始化期间:

// Create shared libray API class instance to access dll module features.
mp_sharedlib_api = new shareLibAPIClass( this );
以及稍后在Qt应用程序中:

// Connect signal/slot between shared library and Qt application
connect(
    mp_sharedlib_api , SIGNAL( SignalUpdateGUIStatus( QString ) ),
    this, SLOT( SlotUpdateGUIStatus( QString ) )
    );
这是开发使用共享库的Qt项目的正确方法吗?共享库的API文档是什么?API文档是否列出了共享库发送/处理的信号和插槽


提前感谢。

您不应该想到通过信号和插槽连接的两个库,而是一组类/类实例、一组后端相关类和一组UI相关类。UI类使用后端类(但决不能相反)。这两组类在不同的库中是部署的实现细节,并且对于C++级的应用程序设计来说大多无关。即使所有代码在单个应用程序中链接在一起,设计概念也是相同的

用一个信号创建一个“公共类”
signalUpdateGUIStatus(QString)
,很可能是错误的方法。仅仅因为接口是一个单独的库,就将其限制为单个类甚至信号是没有意义的。小型接口很好——但除非后端代码只发送一种非常特定的更新,“SignalUpdateUstatus(QString WhatChangedCodeDassString)”将通过单个类/信号完成太多的工作。 signalUpdateGUIStatus还意味着后端库知道有一个UI。不应该。它只提供有关网络上设备的信息——是否有一个UI显示信息,或者一些机器人通过电子邮件(或其他方式)发送通知,这与它无关

您可以拥有一个共享库,其中包含导出的类,如LightSensorListener、TemperatureSensorListener等(或仅限于DeviceListener,具体取决于),这些类可以是值更改时发出信号的QoObject,但也可以具有任何其他Q_属性、方法,这些类将在应用程序中实例化,然后连接到UI代码

想想在应用程序中如何使用Qt。您的库将是另一个库,您使用它的类从网络获取数据。就像您使用QString、QWidget、QLineEdit等创建UI并与之交互一样,您将使用库的类与网络进行接口:

假设我们的库“foo”有一个类温度传感器:

 //file TemperatureSensor.h

 /**
  * A temperature sensor on the network.
  * yaddayaddayadda
  */
 class FOO_EXPORT TemperatureSensor {
      Q_OBJECT
      Q_PROPERTY(QString address READ address WRITE setAddress NOTIFY addressChanged)
      Q_PROPERTY(bool available READ available NOTIFY availableChanged)
      Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged) 
 public:
      /**
       * Creates a temperature sensor
       *
       * @param parent parent QObject
       */
      explicit TemperatureSensor(QObject* parent=0);

      /**
       * Returns whether the device is currently available and delivering data
       */
      bool available() const;
      /**
       * Returns the temperature reported by the sensor (In Celsius)
       */
      qreal temperature() const;

      /**
       * Makes the device explode. Use with caution!
       * Don't give this to little developers/children.
       */          
      void blowUp();

      //address(), setAddress() etc...
 Q_SIGNALS:
      /**
       * The availability of the sensor changed
       *
       * @param available whether the sensor is now available
       */
      void availableChanged(bool available);
      void temperatureChanged(qreal);
      void addressChanged(const QString&);
 };
然后,在应用程序中,您只需创建实例并将其与UI连接:

 TemperatureSensor sensor;
 sensor.setAddress("/tempsensors/1234");

 TemperaturWidget widget;
 widget.show();
 //connect signals from sensor, or pass the whole sensor instance, etc.

对于文档,应记录库的所有公共类(即导出的所有内容)。信号/插槽通常与其他“正常”方法一样进行记录。

您不应该想到通过信号和插槽连接的两个库,而是一组类/类实例、一组后端相关类和一组UI相关类。UI类使用后端类(但决不能相反)。这两组类在不同的库中是部署的实现细节,并且对于C++级的应用程序设计来说大多无关。即使所有代码在单个应用程序中链接在一起,设计概念也是相同的

用一个信号创建一个“公共类”
signalUpdateGUIStatus(QString)
,很可能是错误的方法。仅仅因为接口是一个单独的库,就将其限制为单个类甚至信号是没有意义的。小型接口很好——但除非后端代码只发送一种非常特定的更新,“SignalUpdateUstatus(QString WhatChangedCodeDassString)”将通过单个类/信号完成太多的工作。 signalUpdateGUIStatus还意味着后端库知道有一个UI。不应该。它只提供有关网络上设备的信息——是否有一个UI显示信息,或者一些机器人通过电子邮件(或其他方式)发送通知,这与它无关

您可以拥有一个共享库,其中包含导出的类,如LightSensorListener、TemperatureSensorListener等(或仅限于DeviceListener,具体取决于),这些类可以是值更改时发出信号的QoObject,但也可以具有任何其他Q_属性、方法,这些类将在应用程序中实例化,然后连接到UI代码

想想在应用程序中如何使用Qt。您的库将是另一个库,您使用它的类从网络获取数据。就像您使用QString、QWidget、QLineEdit等创建UI并与之交互一样,您将使用库的类与网络进行接口:

假设我们的库“foo”有一个类温度传感器:

 //file TemperatureSensor.h

 /**
  * A temperature sensor on the network.
  * yaddayaddayadda
  */
 class FOO_EXPORT TemperatureSensor {
      Q_OBJECT
      Q_PROPERTY(QString address READ address WRITE setAddress NOTIFY addressChanged)
      Q_PROPERTY(bool available READ available NOTIFY availableChanged)
      Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged) 
 public:
      /**
       * Creates a temperature sensor
       *
       * @param parent parent QObject
       */
      explicit TemperatureSensor(QObject* parent=0);

      /**
       * Returns whether the device is currently available and delivering data
       */
      bool available() const;
      /**
       * Returns the temperature reported by the sensor (In Celsius)
       */
      qreal temperature() const;

      /**
       * Makes the device explode. Use with caution!
       * Don't give this to little developers/children.
       */          
      void blowUp();

      //address(), setAddress() etc...
 Q_SIGNALS:
      /**
       * The availability of the sensor changed
       *
       * @param available whether the sensor is now available
       */
      void availableChanged(bool available);
      void temperatureChanged(qreal);
      void addressChanged(const QString&);
 };
然后,在应用程序中,您只需创建实例并将其与UI连接:

 TemperatureSensor sensor;
 sensor.setAddress("/tempsensors/1234");

 TemperaturWidget widget;
 widget.show();
 //connect signals from sensor, or pass the whole sensor instance, etc.
对于文档,应记录库的所有公共类(即导出的所有内容)。信号/插槽通常像其他“正常”方法一样记录在案。

我想你忘了