Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Multi-threading design along with an undo/redo stack



  • I have this call stack to perform a heavy computation:

    // QML
    
    StyledButton {
        onButtonClicked: {
            registeredCppClass.undoHandler.createCommand()
        }
    }
    
    void UndoHandler::createCommand()
    {
        m_undoStack->push(new Command());
    }
    
    class Command : public QUndoCommand
    {
    public:
        Command();
        virtual ~Command();
    
        virtual void undo();
        virtual void redo();
        
        // ...
    private:
        // Handler does the logic
        LogicHandler *m_logicHandler;
        // Output by logic handler
        QString m_outputName;
    };
    
    void Command::redo()
    {
        
        if (/* */) {
            
        } else {
            // Run heavy computation
            m_outputName = m_logicHandler->run();
        }
    }
    
    QString LogicHandler::run()
    {
        // Heavy computation starts
    }
    

    Intention

    I intend to implement QThread by this approach to prevent GUI from getting non-responsive while heavy computation is being done. But I don't know where QThread and Worker class need to be implemented. Should they be within:

    • UndoHandler::createCommand
    • Command::redo
    • LogicHandler::run
    • ... ?

    What is the best location for QThread and Worker considering their signal-slot connections?


  • Qt Champions 2017

    @m3g1dd said in Multi-threading design along with an undo/redo stack:

    What is the best location for QThread and Worker considering their signal-slot connections?

    QThread goes into an object in the controlling thread (usually the GUI thread), while the Worker is usually "free", that is I ordinarily don't keep a reference to it anywhere. Still depends on the actual logic, though, you could wrap a "job" based system, or migrate to QtConcurrent::run depending on the actual situation. Typically if you want to break the processing within a secondary thread (a worker one), you'd connect the interruption method (Qt::DirectConnection) to raise some atomic flag, which is checked on each iteration/atom of code that's executed and exit early when needed.


Log in to reply