简体   繁体   English

如何在Qt中创建一个处理程序?

[英]How to create a handler in Qt?

I'm working on an application using Qt version 4.8 in C++. 我正在使用Qt版本4.8在C ++中开发应用程序。

I need to use a C function which requires a pointer to a free function: 我需要使用一个C函数,它需要一个指向自由函数的指针:

void handler(int dummy)

I need to change the displayed values in my GUI depending on what happens inside the function. 我需要根据函数内部的内容更改GUI中的显示值。

So I've been reading on how to convert a member function to a free function. 所以我一直在阅读如何将成员函数转换为自由函数。 I've found out that I can do it only if my member function is static. 我发现只有当我的成员函数是静态的时我才能做到。

But I can't make it static - I won't be able to change any widgets if I make it static. 但是我不能让它静止 - 如果我把它变成静态的话,我将无法改变任何小部件。

So, how can I deal with the problem? 那么,我该如何处理这个问题呢? How can I pass a non-static member function as a pointer to a free function. 如何将非静态成员函数作为指向自由函数的指针传递。 If it's not possible, how to make a workaround? 如果不可能,如何制定解决方法?

I'll be grateful for any suggestions different that use another library . 对于使用其他库的不同建议,我将不胜感激。

Since the C function takes an argument, you can use the argument as an index into an array of functors: 由于C函数接受一个参数,您可以使用该参数作为仿函数数组的索引:

class MyWidget : public QWidget {
  using vector_t = QVector<std::function<void()>>;
  static vector_t m_functions;
public:
  using function_type = void(*)(int);
  using size_type = vector_t::size_type;

  static function_type getHandler() {
    return +[](int index){ MyWidget::m_functions[index]; };
  }
  template <typename F> static size_type getIndexFor(F && fun) {
    m_functions.append(std::forward<F>(fun));
    return m_functions.size() - 1;
  }
  //...
  size_type getIndexForSetTitle();
};

The getHandler returns the address of the handler function. getHandler返回处理函数的地址。 The getIndexFor returns the argument to be passed to the handler to run a given functor. getIndexFor返回要传递给处理程序的参数以运行给定的仿函数。 The functor can encapsulate calls to the widget's methods. 仿函数可以封装对小部件方法的调用。 Here, we'll call setWindowTitle on the widget: 在这里,我们将在小部件上调用setWindowTitle

MyWidget::size_type MyWidget::getIndexForSetTitle() {
  static size_type index = getIndexFor([this]{ setWindowTitle("Foo"); });
  return index;
}

Yes, C++ does not allow member functions to be passed as a function pointer to C libraries. 是的,C ++不允许将成员函数作为函数指针传递给C库。

In this cases a common approach is using a helper function that acts like a bridge between the C library and our class instance. 在这种情况下,一种常见的方法是使用辅助函数,它就像C库和类实例之间的桥梁。 This helper function is a free function that takes a pointer to the current instance of the class and in its body invoke the corresponding member method of the class instance. 这个辅助函数是一个自由函数,它接受指向类的当前实例的指针,并在其体内调用类实例的相应成员方法。

void handler_helper(int data){
    MyClass *obj = (MyClass *) data;
    obj->handler(); // This is the corresponding member method
}

And where you invoke a function from that C library, you should pass handler_helper as the function pointer and (int) this as its argument. 在从C库调用函数的地方,您应该将handler_helper作为函数指针传递,并将(int) this作为参数传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM