首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QDbus信号不工作(传送暂停)

QDbus信号不工作(传送暂停)
EN

Stack Overflow用户
提问于 2021-05-03 21:55:00
回答 1查看 216关注 0票数 0

在我的项目中,我需要在信号中使用DBus。为此,我尝试将D总线遥控汽车实例上可用的示例程序转换为在linux A7处理器上运行(所使用的QT5.12.8)。我认识到以下步骤:

  1. 用文本输出和辛化程序替换所有的人机界面引用。
  2. 将项目迁移到qmake的位置使用CMake (在最终项目中使用的Cmake> 3.0 )

car文件夹中的CMakeLists.txt:

代码语言:javascript
复制
set(QT_LIBS Qt5::Core Qt5::DBus)

add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/car_adaptor.h ${CMAKE_CURRENT_SOURCE_DIR}/car_adaptor.cpp
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/car.xml
  COMMENT "Generate adaptors files for Dbus service"
  COMMAND /opt/dip/2.7-warrior+snapshot/sysroots/x86_64-dipsdk-linux/usr/bin/qdbusxml2cpp -a car_adaptor.h: ${CMAKE_CURRENT_SOURCE_DIR}/car.xml
  COMMAND /opt/dip/2.7-warrior+snapshot/sysroots/x86_64-dipsdk-linux/usr/bin/qdbusxml2cpp -i car_adaptor.h -a :car_adaptor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/car.xml
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_executable (car 
  main.cpp 
  car.cpp
  car_adaptor.cpp
)

set_target_properties(car PROPERTIES AUTOMOC TRUE)
target_link_libraries(car ${QT_LIBS})

控制器文件夹中的CMakeLists.txt:

代码语言:javascript
复制
set(QT_LIBS Qt5::Core Qt5::DBus)

add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/car_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/car_interface.cpp
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/car.xml
  COMMENT "Generate interface files for Dbus service"
  COMMAND /opt/dip/2.7-warrior+snapshot/sysroots/x86_64-dipsdk-linux/usr/bin/qdbusxml2cpp -p car_interface.h: ${CMAKE_CURRENT_SOURCE_DIR}/car.xml
  COMMAND /opt/dip/2.7-warrior+snapshot/sysroots/x86_64-dipsdk-linux/usr/bin/qdbusxml2cpp -i car_interface.h -p :car_interface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/car.xml
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_executable (controller 
  main.cpp 
  controller.cpp
  car_interface.cpp
) 

set_target_properties(controller PROPERTIES AUTOMOC TRUE)
target_link_libraries(controller ${QT_LIBS})

问题描述

我的问题是:随着这些变化,Dbus信号似乎是由汽车应用程序发出的,而控制器应用程序却没有接收到。我试图理解(QDBUS_DEBUG=1)调试模式出现问题的原因,但不理解为什么所有信号都有以下返回: DBus (0x75d006d0)传递暂停,我可能错过了一件事,但我看不出是什么。

测试输出:

代码语言:javascript
复制
export QDBUS_DEBUG=1
eval `dbus-launch --auto-syntax`
root@rzn1-embd:/tmp# ./car &
[1] 1391
root@rzn1-embd:/tmp# QDBusConnectionPrivate(0x75d006d0) : connected successfully
QDBusConnectionPrivate(0x75d006d0) got message (signal): QDBusMessage(type=Signal, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="NameAcquired", signature="s", contents=(":1.0") )
QDBusConnectionPrivate(0x75d006d0) sending message: QDBusMessage(type=MethodCall, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="RequestName", signature="", contents=("org.example.CarExample", 4) )
QDBusConnectionPrivate(0x75d006d0) delivery is suspended
QDBusConnectionPrivate(0x75d006d0) got message (signal): QDBusMessage(type=Signal, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="NameAcquired", signature="s", contents=("org.example.CarExample") )
QDBusConnectionPrivate(0x75d006d0) delivery is suspended
QDBusConnectionPrivate(0x75d006d0) got message reply: QDBusMessage(type=MethodReturn, service="org.freedesktop.DBus", signature="u", contents=(1) )
QDBusConnectionPrivate(0x75d006d0) dequeueing message QDBusMessage(type=Signal, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="NameAcquired", signature="s", contents=(":1.0") )
QDBusConnectionPrivate(0x75d006d0) dequeueing message QDBusMessage(type=Signal, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="NameAcquired", signature="s", contents=("org.example.CarExample") )
root@rzn1-embd:/tmp# ./controller
QDBusConnectionPrivate(0x75d006d0) : connected successfully
QDBusConnectionPrivate(0x75d006d0) got message (signal): QDBusMessage(type=Signal, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="NameAcquired", signature="s", contents=(":1.1") )
QDBusConnectionPrivate(0x75d006d0) delivery is suspended
QDBusConnectionPrivate(0x75d006d0) Adding rule: "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.example.CarExample'"
QDBusConnectionPrivate(0x75d006d0) sending message: QDBusMessage(type=MethodCall, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="GetNameOwner", signature="", contents=("org.example.CarExample") )
QDBusConnectionPrivate(0x75d006d0) got message reply: QDBusMessage(type=MethodReturn, service="org.freedesktop.DBus", signature="s", contents=(":1.0") )
QDBusConnectionPrivate(0x75d006d0) Adding rule: "type='signal',sender='org.example.CarExample',path='/Car',interface='org.example.Examples.CarInterface',member='crashed'"
QDBusConnectionPrivate(0x75d006d0) sending message: QDBusMessage(type=MethodCall, service="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="GetNameOwner", signature="", contents=("org.example.CarExample") )
QDBusConnectionPrivate(0x75d006d0) got message reply: QDBusMessage(type=MethodReturn, service="org.freedesktop.DBus", signature="s", contents=(":1.0") )
QDBusConnectionPrivate(0x75d006d0) Watching service "org.example.CarExample" for owner changes (current owner: ":1.0" )

Menu:
        - Q: quitter
        - 1: Accelerate
        - 2: Decelerate
1
QDBusConnectionPrivate(0x75d006d0) sending message: QDBusMessage(type=MethodCall, service="org.example.CarExample", path="/Car", interface="org.example.Examples.CarInterface", member="accelerate", signature="", contents=() )
QDBusConnectionPrivate(0x75d006d0) got message (signal): QDBusMessage(type=MethodCall, service=":1.1", path="/Car", interface="org.example.Examples.CarInterface", member="accelerate", signature="", contents=() )
Speed:  1
QDBusConnectionPrivate(0x75d006d0) Automatically sending reply: ()
QDBusConnectionPrivate(0x75d006d0) sending message (no reply): QDBusMessage(type=MethodReturn, service="", signature="", contents=() )
QDBusConnectionPrivate(0x75d006d0) got message reply: QDBusMessage(type=MethodReturn, service=":1.0", signature="", contents=() )
QThread(ptr=0x76f0d370, name=QDBusConnectionManager) emitting signal at "/Car"
QDBusConnectionPrivate(0x75d006d0) got message (signal): QDBusMessage(type=Signal, service=":1.0", path="/Car", interface="org.example.Examples.CarInterface", member="crashed", signature="", contents=() )
QDBusConnectionPrivate(0x75d006d0) delivery is suspended

修改后的源文件:

car.h

代码语言:javascript
复制
#ifndef CAR_H
#define CAR_H

#include <QObject>

class Car : public QObject
{
    Q_OBJECT
public:
    Car();

public Q_SLOTS:
    void accelerate();
    void decelerate();

Q_SIGNALS:
    void crashed();

private:
    int speed;       // delta movement along the body axis
};

#endif // CAR_H

car.cpp

代码语言:javascript
复制
#include "car.h"
#include <QDebug>

Car::Car() : speed(0) {}

void Car::accelerate() {
  if (speed < 10) 
    ++speed; 
  qInfo() << "Speed: " << speed << endl;
  if (speed > 0) 
    emit crashed(); 
}

void Car::decelerate() {
  if (speed > -10) 
    --speed;
  qInfo() << "Speed: " << speed << endl;
}

car/main.cpp

代码语言:javascript
复制
#include "car.h"
#include "car_adaptor.h"
#include <QCoreApplication>
#include <QtDBus/QDBusConnection>

int main(int argc, char *argv[]) {
  QCoreApplication app(argc, argv);

  Car *car = new Car();
  new CarInterfaceAdaptor(car);
  QDBusConnection connection = QDBusConnection::sessionBus();
  connection.registerObject("/Car", car);
  connection.registerService("org.example.CarExample");
  return app.exec();
}

控制器/main.cpp

代码语言:javascript
复制
#include <QtDBus>
#include <QCoreApplication>
#include "controller.h"

int main(int argc, char *argv[]) {
  QCoreApplication app(argc, argv);
  Controller       controller;
  controller.start();
  return app.exec();
}

controller.h

代码语言:javascript
复制
#ifndef CONTROLLER_H
#define CONTROLLER_H

#include "car_interface.h"
#include <QObject>

class Controller : public QObject
{
    Q_OBJECT

public:
    Controller(QObject *parent = 0);
    void start();

private slots:
    void on_accelerate_clicked();
    void on_decelerate_clicked();
    void onCrashed();

private:
    org::example::Examples::CarInterface *car;
    void displayMenu();
};
#endif

controller.cpp

代码语言:javascript
复制
#include "controller.h"
#include "car_interface.h"
#include <QDebug>

Controller::Controller(QObject *parent) : QObject(parent) {
  car = new org::example::Examples::CarInterface(
      "org.example.CarExample", "/Car", QDBusConnection::sessionBus(), this);
  connect(car, SIGNAL(crashed()), this, SLOT(onCrashed()));
}

void Controller::start() {
  char key = 0;
  displayMenu();
  while (key != 'Q') {
    key = getchar();
    switch (key) {
      case '1': on_accelerate_clicked(); break;
      case '2': on_decelerate_clicked(); break;
      case 'Q': exit(1); break;
    }
  }
}

void Controller::on_accelerate_clicked() { car->accelerate(); }

void Controller::on_decelerate_clicked() { car->decelerate(); }

void Controller::onCrashed() { qInfo() << "Controller: crashed"; }

void Controller::displayMenu() {
  qInfo() << "\r\nMenu:";
  qInfo() << "\t- Q: quitter";
  qInfo() << "\t- 1: Accelerate";
  qInfo() << "\t- 2: Decelerate";
}
EN

回答 1

Stack Overflow用户

发布于 2022-01-14 12:33:13

在控制器的main()函数中,执行从不经过controller.start(),因为该方法包含连续轮询键盘输入的while循环,如果按下"Q“,它将立即退出。

因此,您永远不会到达运行Qt事件循环的app.exec(),并且只在事件循环中接收和处理DBus信号。

您应该切换到处理键盘按下事件的基础上。或者,如果您想保持while循环,您应该修改它,以便至少经常调用QCoreApplication::processEvents() (请参阅其文档)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67376297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档