Qt C++ 信号和槽没有触发
Posted
技术标签:
【中文标题】Qt C++ 信号和槽没有触发【英文标题】:Qt C++ signals and slots did not fire 【发布时间】:2014-05-27 16:20:25 【问题描述】:我已经对 Qt 编程过几次,我非常喜欢信号和插槽功能。但是现在,我想当一个线程发出信号时我遇到了问题,另一个线程的相应插槽没有被触发。连接是在主程序中建立的。
这也是我第一次使用使用 CMake 的 Qt for ROS。 QThread 触发的信号触发了它们相应的槽,但我的类 UserInput 发出的信号没有触发它应该触发的 tflistener 中的槽。我已经尽我所能。有什么帮助吗?代码如下。
Main.cpp
#include <QCoreApplication>
#include <QThread>
#include "userinput.h"
#include "tfcompleter.h"
int main(int argc, char** argv)
QCoreApplication app(argc, argv);
QThread *thread1 = new QThread();
QThread *thread2 = new QThread();
UserInput *input1 = new UserInput();
TfCompleter *completer = new TfCompleter();
QObject::connect(input1, SIGNAL(togglePause2()), completer, SLOT(toggle()));
QObject::connect(thread1, SIGNAL(started()), completer, SLOT(startCounting()));
QObject::connect(thread2, SIGNAL(started()), input1, SLOT(start()));
completer->moveToThread(thread1);
input1->moveToThread(thread2);
thread1->start();
thread2->start();
app.exec();
return 0;
我想要做的是.. 有两个单独的线程。一个线程用于用户输入。当用户输入 [space] 时,线程会发出一个信号来切换另一个线程的布尔成员字段。另一个线程的任务是如果用户希望它运行则继续其进程,否则用户不希望它运行。我想授予用户在他想要的任何时候切换处理,这就是为什么我决定将它们带入单独的线程。
以下代码是tflistener和userinput。
tfcompleter.h
#ifndef TFCOMPLETER_H
#define TFCOMPLETER_H
#include <QObject>
#include <QtCore>
class TfCompleter : public QObject
Q_OBJECT
private:
bool isCount;
public Q_SLOTS:
void toggle();
void startCounting();
;
#endif
tflistener.cpp
#include "tfcompleter.h"
#include <iostream>
void TfCompleter::startCounting()
static uint i = 0;
while(true)
if(isCount)
std::cout << i++ << std::endl;
void TfCompleter::toggle()
// isCount = ~isCount;
std::cout << "isCount " << std::endl;
用户输入.h
#ifndef USERINPUT_H
#define USERINPUT_H
#include <QObject>
#include <QtCore>
class UserInput : public QObject
Q_OBJECT
public Q_SLOTS:
void start(); // Waits for the keypress from the user and emits the corresponding signal.
public:
Q_SIGNALS:
void togglePause2();
;
#endif
用户输入.cpp
#include "userinput.h"
#include <iostream>
#include <cstdio>
// Implementation of getch
#include <termios.h>
#include <unistd.h>
/* reads from keypress, doesn't echo */
int getch(void)
struct termios oldattr, newattr;
int ch;
tcgetattr( STDIN_FILENO, &oldattr );
newattr = oldattr;
newattr.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
return ch;
void UserInput::start()
char c = 0;
while (true)
c = getch();
if (c == ' ')
Q_EMIT togglePause2();
std::cout << "SPACE" << std::endl;
c = 0;
这里是 CMakeLists.txt。我也只是把它放在这里,因为我不知道 CMake 是否也有一个因素。
CMakeLists.txt
##############################################################################
# CMake
##############################################################################
cmake_minimum_required(VERSION 2.4.6)
##############################################################################
# Ros Initialisation
##############################################################################
include($ENVROS_ROOT/core/rosbuild/rosbuild.cmake)
rosbuild_init()
set(CMAKE_AUTOMOC ON)
#set the default path for built executables to the "bin" directory
set(EXECUTABLE_OUTPUT_PATH $PROJECT_SOURCE_DIR/bin)
#set the default path for built libraries to the "lib" directory
set(LIBRARY_OUTPUT_PATH $PROJECT_SOURCE_DIR/lib)
# Set the build type. Options are:
# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage
# Debug : w/ debug symbols, w/o optimization
# Release : w/o debug symbols, w/ optimization
# RelWithDebInfo : w/ debug symbols, w/ optimization
# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries
#set(ROS_BUILD_TYPE Debug)
##############################################################################
# Qt Environment
##############################################################################
# Could use this, but qt-ros would need an updated deb, instead we'll move to catkin
# rosbuild_include(qt_build qt-ros)
rosbuild_find_ros_package(qt_build)
include($qt_build_PACKAGE_PATH/qt-ros.cmake)
rosbuild_prepare_qt4(QtCore) # Add the appropriate components to the component list here
ADD_DEFINITIONS(-DQT_NO_KEYWORDS)
##############################################################################
# Sections
##############################################################################
#file(GLOB QT_FORMS RELATIVE $CMAKE_CURRENT_SOURCE_DIR ui/*.ui)
#file(GLOB QT_RESOURCES RELATIVE $CMAKE_CURRENT_SOURCE_DIR resources/*.qrc)
file(GLOB_RECURSE QT_MOC RELATIVE $CMAKE_CURRENT_SOURCE_DIR FOLLOW_SYMLINKS include/rgbdslam_client/*.hpp)
#QT4_ADD_RESOURCES(QT_RESOURCES_CPP $QT_RESOURCES)
#QT4_WRAP_UI(QT_FORMS_HPP $QT_FORMS)
QT4_WRAP_CPP(QT_MOC_HPP $QT_MOC)
##############################################################################
# Sources
##############################################################################
file(GLOB_RECURSE QT_SOURCES RELATIVE $CMAKE_CURRENT_SOURCE_DIR FOLLOW_SYMLINKS src/*.cpp)
##############################################################################
# Binaries
##############################################################################
rosbuild_add_executable(rgbdslam_client $QT_SOURCES $QT_MOC_HPP)
#rosbuild_add_executable(rgbdslam_client $QT_SOURCES $QT_RESOURCES_CPP $QT_FORMS_HPP $QT_MOC_HPP)
target_link_libraries(rgbdslam_client $QT_LIBRARIES)
【问题讨论】:
首先,要查看的代码太多。您应该尝试缩小问题的范围以获得更好的帮助。第二,你说它不起作用...什么不起作用,你是怎么得出这个结论的? 【参考方案1】:很难从您发布的代码中找到错误。我只想指出一个问题:
您首先建立连接,然后将对象移动到新线程。因为它们是在同一个线程中创建的,所以它们具有相同的Thread Affinity。所以默认情况下连接类型是direct,这意味着slot
将在发出signal
的同一个线程中执行。
但是在移动到新线程之后,两个对象的线程亲和性都发生了变化。虽然你没有说你怎么会发现它不起作用,但我建议你看看这个问题。如果您希望 slot
在不同的线程中执行,并以这种方式进行测试,那么您可能无法获得所需的输出并认为它不起作用。
当signal
和slot
打算在不同的线程中执行时,最好在将相应的对象移动到新线程后将它们连接起来。当对象在不同的线程中时,Qt::AutoConnection
默认使用Qt::QueuedConnection
。
【讨论】:
编辑了我的帖子。那么,当信号和槽处于不同的线程关联中时,如何连接它们呢?以上是关于Qt C++ 信号和槽没有触发的主要内容,如果未能解决你的问题,请参考以下文章