Chciałbym mieć osobną kolejkę gwintową A std::function do wykonywania w głównym wątku aplikacji QT, jak to możliwe, co najmniej, co oznacza, że wykonanie tej funkcji ma pierwszeństwo przed czymś innym, co dzieje się w Główny wątek, Zapisz dla każdego zadania Główny wątek jest obecnie wykonujący. (Aby wyjaśnić, obecnie wykonywanie zadania w głównym wątku nie musi dawać wykonania lub nic takiego

Istnieje wiele sposobów, w jakie można ustawić funkcję, która ma być wywoływana w innym określonym {x0}}, takiej jak przy użyciu pojedynczego strzału {X1}} za pomocą zerowego drugiego interwału lub przy użyciu QMetaObject::invokeMethod. Ale nie jestem pewien, jak wykonanie funkcji będzie priorytetowe w odniesieniu do innych zadań, które są przetwarzane przez gwint główny.

Pierwsza myśl, którą miałem, było stworzenie niestandardowej QEvent, która zawiera instancję funkcji, którą chcę wykonać, napisz obsługiwanie nowego typu zdarzenia niestandardowego, który wykonuje funkcję, a następnie opublikuj go za pomocą czegoś takiego:

qApp->postEvent(qApp, customEvent, Qt::HighEventPriority * 1000000);

... lub używając innego odpowiedniego ogromnego całkowitego liczności całkowitej. Nie jestem pewien, czy jest to najlepszy sposób na robienie tego, ponieważ nie mam głębokiej wiedzy o tym, jak działa system zdarzenia QT. (Podobnie jak to byłoby priorytetowe w odniesieniu do zdarzeń wysłanych do innych QObject, którego powinowactwo wątku jest ustawione na gwint główny?)

Czy jest lepsza metoda?

0
GuyGizmo 25 październik 2020, 02:33

1 odpowiedź

Najlepsza odpowiedź

Oto rozwiązanie, na którym się osiedliłem:

#define kFunctionEventType ((QEvent::Type)(QEvent::User + 1))

class FunctionEvent : public QEvent {
public:
    FunctionEvent(const std::function<void()> &inFunc) : QEvent(kFunctionEventType), func(inFunc){};
    std::function<void()> func;
};

class FunctionEventReceiver : public QObject {
    Q_OBJECT
public:
    explicit FunctionEventReceiver() : QObject(nullptr) {};
    virtual bool event(QEvent *event);
};

static FunctionEventReceiver * functionEventReceiver()
{
    static FunctionEventReceiver receiver;
    return &receiver;
}

bool FunctionEventReceiver::event(QEvent *event)
{
    if (event->type() != kFunctionEventType) {
        return QObject::event(event);
    }
    
    FunctionEvent *functionEvent = (FunctionEvent *)event;
    functionEvent->func();
    functionEvent->accept();
    
    return true;
}

void executeInMainThreadWithMaximumPriority(const std::function<void ()> &func)
{
    FunctionEvent *event = new FunctionEvent(func);
    qApp->postEvent(functionEventReceiver(), event, INT_MAX);
}

void initialize()
{
    // Ensures receiver is created in main thread:
    functionEventReceiver();
}

Jedynym zastrzeżeniem jest to, że muszę zadzwonić initialize() na początku mojej aplikacji, aby upewnić się, że odbiornik zdarzeń zostanie utworzony i powiązany z głównym wątkiem aplikacji.

0
GuyGizmo 27 październik 2020, 18:01