Создание динамического слота в Qt - PullRequest
11 голосов
/ 19 апреля 2011

Я пытаюсь динамически создавать слоты и соединять их.Я могу динамически создавать кнопки и соединять их с существующими слотами.Но что, если у меня есть класс с некоторыми функциями-членами, и я хочу использовать эти функции в качестве слотов.

В общих чертах я хочу создать шаблон для генерации слотов с помощью указателя на функцию.Это позволяет нам создавать слоты без изменения существующего кода и не нужно перекомпилировать с помощью MOC.Если это не имеет смысла, дайте мне знать.Спасибо.

-CV

Ответы [ 2 ]

11 голосов
/ 19 апреля 2011

Это имеет большой смысл. Я полагаю, QSignalMapper не то, что вы хотите. Если у ваших функций нет аргументов, возможно, вам достаточно что-то вроде этого:

class SlotForwarder : public QObject
{
    Q_OBJECT

public:

    typedef void (*Function)(); // or whatever. I never get this syntax right...

    SlotForwarder(Function function, QObject* parent = 0) 
        : QObject(parent)
        , m_fptr(function)
    {}

public slots:

    void forward()
    {
        m_fptr();
    }

private:

    Function m_fptr;
};

Создайте по одной для каждой функции, которую вы хотите инкапсулировать, и подключите к forward как обычно.


Теперь, если у них есть аргументы, возможно, эта статья Qt Quarterly может помочь.

Динамические сигналы и слоты Эскил А. Бломфельдт

Техника включает в себя переопределение метода qt_metacall самостоятельно. У метода есть такая подпись:

int QObject::qt_metacall(QMetaObject::Call call, int id, void **arguments)

Call - это вид метаколла: слот, сигнал, чтение или запись свойства и т. Д. Каждый слот имеет id . Параметры упакованы (по значению или в виде указателей) внутри массива arguments . Чтение кода, сгенерированного moc, является хорошим способом понять, как все это работает.

Данные о необработанных сигнатурах функций доступны только во время компиляции, но слоты разрешаются во время выполнения. Из-за этого несоответствия вам нужно будет обернуть функции в тип адаптера шаблона, который представляет постоянный интерфейс для вашей реализации qt_metacall и преобразует массив arguments в то, что функция может понять (см. Python распаковать оператор). Boost.Signals делает шаблонный взлом .

3 голосов
/ 21 апреля 2011

Продолжение кода andref, чтобы использовать любую функцию-член в качестве слота

    class SlotForwarder : public QObject
    {
        Q_OBJECT

    public:

        typedef void (*Function)();

        SlotForwarder(Function function, QObject* parent = 0) 
            : QObject(parent)
            , m_fptr(function)
        {}

    public slots:

        void forward()
        {
            m_fptr();
        }

    private:

        Function m_fptr;
    };

    int main(){
      QApplication a(argc, argv);
      MyClass myClassObject; //contains a function called MemberFunc
      //create a slotforwarder object so 
      SlotForwarder *memberFuncSlot = new SlotForwarder (std::tr1::bind(&MyClass::MemberFunc, &myClassObject));
      QObject::connect(ui.button,SIGNAL(clicked()),memberFuncSlot,SLOT(forward());
    }
...