来自静态方法的QT信号

时间:2018-01-31 11:04:09

标签: c++ qt callback signals-slots

我需要从静态回调函数发送信号。我做了以下事情:

·H

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow (QWidget* parent=0);
    ~MainWindow();
    static MainWindow* getInstance();
private:
    void emitSignal();
    static MainWindow* m_instance;
signals:
    void mysignal();
slots: 
    void print();
 ...
}        

的.cpp

MainWindow* MainWindow::m_instance = 0;
MainWindow::MainWindow(QWidget* parent):
QMainWindow(parent) {
...
}

MainWindow* MainWindow::getInstance() {
if (m_instance == 0)
    m_instance = new MainWindow;
return m_instance;
}

void MainWindow::emitSignal() {
    emit mysignal();
}

回调函数内部:

getInstance()->emitSignal();

以及代码中的某处:

connect(MainWindow::getInstance(), SIGNAL(mysignal()), this, SLOT(print()));

但是不执行slot print()。并且不会打印错误。我哪里错了?

2 个答案:

答案 0 :(得分:2)

回调使用getInstance(),因此肯定会创建一个新的小部件,如果还没有。那么问题就是你如何理解执行回调的代码。如果在建立连接之前进行了回调,则不会调用该插槽。这可能是你的问题。在没有实例的情况下调用回调是无效的,你应该断言它是如此。

最有可能的是,您不需要动态创建主窗口的实例。您可能面临一个XY问题,您认为自己需要做某事,但是您已经投入了一个不起作用的解决方案,而您没有看到您遇到的更大问题&# 39;重新尝试解决。请清楚地了解您的应用程序究竟是什么 - 为什么要动态创建窗口?

除非你真的需要信号是私有的,否则也没有必要创建一个转发信号的方法。我怀疑你这样做 - 不要把它变成私密的。

以下代码表明,如果您正确执行此操作,您尝试执行的操作肯定会有效:

// https://github.com/KubaO/stackoverflown/tree/master/questions/static-signal-48540601
#include <QtCore>

class Main : public QObject {
   Q_OBJECT
   static Main * m_instance;
public:
   Main(QObject * parent = {}) : QObject(parent) {
      Q_ASSERT(! hasInstance());
      m_instance = this;
   }
   static Main * instance() {
      if (! m_instance) m_instance = new Main;
      return m_instance;
   }
   static bool hasInstance() { return m_instance; }
   Q_SIGNAL void theSignal();
};

Main * Main::m_instance;

void callback() {
   Q_ASSERT(Main::hasInstance());
   // If the instance didn't exist here, nothing can receive the signal.
   Main::instance()->theSignal();
}

int main()
{
   int slotCalls = {};
   Main object;
   QObject::connect(&object, &Main::theSignal, [&]{ slotCalls ++; });
   Q_ASSERT(slotCalls == 0);
   callback();
   Q_ASSERT(slotCalls == 1);
}

#include "main.moc"

答案 1 :(得分:0)

您确定信号是否连接到插槽?

为了避免打字错误,你可以使用这种语法(只要你没有过载信号/插槽你就可以了):

connect(MainWindow::getInstance(), &MainWindow::mysignal, this, &MainWindow::print);

另一个提示/样式指南:将您的信号命名为signal_mySignal和像slot_print这样的广告位,以避免拼写错误并清除错误。

你也可以从你主要的某个地方(当然是在连接之后)调用this->dumpObjectInfo();并看一下输出