【问题标题】:How to emit signal from static function in QT?如何从 QT 中的静态函数发出信号?
【发布时间】:2019-08-19 12:18:17
【问题描述】:

我正在尝试从 QT 5 中的同一成员向另一个插槽发出来自静态成员函数的信号。

在我的代码中,我必须调用我作为 MainWindow 成员创建的静态 Gstreamer 函数,以便它可以向其他 MainWindow 插槽发出信号。我的代码是这样的:

主窗口.cpp

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{


ui->setupUi(this);


connect(this, SIGNAL(emitSignal(int)), this, 
SLOT(signal_triggered(int)));

  GMainLoop *loop = NULL;
  gst_init (0, NULL);
  loop = g_main_loop_new (NULL, FALSE);
 ...........
...........

decoder_src_pad = gst_element_get_static_pad (decoder, "src");
  if (!decoder_src_pad)
    g_print ("Unable to get src pad\n");
  else
    gst_pad_add_probe (decoder_src_pad, GST_PAD_PROBE_TYPE_BUFFER,
        decoder_src_pad_buffer_probe, NULL, NULL);   // Must require 
Static function for CALLBACK

g_main_loop_run (loop);

}


GstPadProbeReturn decoder_src_pad_buffer_probe (GstPad * pad, 
GstPadProbeInfo * info, gpointer u_data)
{
GstBuffer *buf = (GstBuffer *) info->data;

int foo = 8;

emit emitSignal(foo); 

return GST_PAD_PROBE_OK;
}

void MainWindow::signal_triggered(int indx)
{

emit requestUpdate(indx); // Signal is connected to another class

}

主窗口.h

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
static GstPadProbeReturn decoder_src_pad_buffer_probe (GstPad * pad, 
GstPadProbeInfo * info, gpointer u_data);

public slots:
void signal_triggered(int);
signals:
void emitSignal(int index);
private:
Ui::MainWindow *ui;
.......
.......
}

但是QT编译器报错:

mainwindow.cpp:116: error: cannot call member function ‘void MainWindow::emitSignal(int)’ without object

我也试过了

emit ui->emitSignal(foo);

但它也会报错:

error: invalid use of member ‘MainWindow::ui’ in static member function emit ui->emitSignal(foo);

【问题讨论】:

  • 尝试用 QObject 的单例实例替换静态方法,这将包含您需要的所有信号
  • 要发出信号,您需要一个信号实例。该信号是派生自QObject 的类的成员。因此,您需要该容器对象的实例。如果要从回调函数发出信号,则必须将实例的地址作为客户端数据传递。然后为该实例发出信号。
  • 正如编译器所说,你不能那样做。信号是从对象实例发出的,从不为实例调用静态函数。如果您告诉我们更多有关您的问题的信息,我们可能会提出解决方案....
  • @SerhiyKulish 请不要建议或这样做。这种单例滥用会在以后给你带来很大的麻烦,并使软件无法维护......
  • 顺便说一句。 Qt 小部件应用程序需要运行时循环才能激活。这就是您拨打QApplication::exec() 时发生的情况。如果您在例如启动另一个(Glib)运行时循环MainWindow 的构造函数,您将永远无法达到对 QApplication::exec() 的必要调用(或者至少,为时已晚)。

标签: c++ qt static signals gstreamer


【解决方案1】:

静态函数无法访问非静态成员或函数(您没有this 指针)。

因此,您不能(直接)从静态函数发出信号 - 哪个 QObject 应该是该信号的发射器(即您将 connect 发送到哪个 QObject?)

问自己:“我为什么要尝试从静态函数发出信号?”并尝试发现并解决根本问题。从长远来看,你会省去很多麻烦。

【讨论】:

    【解决方案2】:

    mainwindow.cpp:116: error: cannot call member function ‘void MainWindow::emitSignal(int)’ without object

    错误是明确的。

    事实上,信号(就像类的每个非静态成员/方法一样)依赖于类的活实例。 static 方法不需要创建任何实例,因此使用相关类的信号是不可能的(如果您尝试访问相关类的非静态成员/方法,方法相同)。

    如果你想发送这个信号,要么你必须删除 static 说明符(这不是你想要的),要么你可以传递类实例的引用作为 static 的参数函数(并从该实例发送所需的信号)。

    【讨论】:

    • 我也考虑过这种方式(即传递类实例的引用作为静态函数的参数)但由于我仍然不清楚如何将参数传递给 GST_PAD_PROBE_TYPE_BUFFER,所以我没有没试过。
    • @AbuAnasShuvom 我的意思是将它作为decoder_src_pad_buffer_probe() 的参数传递(这是static 函数)。我不知道GST_PAD_PROBE_TYPE_BUFFER 是什么,但代码不够完整,我无法理解真正的问题。无论如何,我希望它可以帮助您找到合适的解决方案:)
    【解决方案3】:

    您可以使用单例模式。让你的班级像这样: enter link description here

    并像这样使用发射:

        emit yourclassInstance->DataReady(samples);
    

    【讨论】:

      猜你喜欢
      • 2018-02-27
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 2013-06-13
      • 2021-06-08
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多