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

How can i stop a thread running in my Dialog Class from my mainWindow



  • My mainwindow looks like this

    85c350df-beef-47b7-bab4-1cffa4e0377a-image.png

    it is a qlistwidget with some Job items, whenever any job item is clicked , it shows up the QDialogbox which looks like this.

    555423d8-71c1-4b54-ba16-68303d7c5a47-image.png

    The QDialog has a listwidget and a show button, whenever the show button is clicked , a list of 10000 possible employees will show up in the Qlistwidget and these employees are calculated by this function which is in a thread3.

    ```
    

    void KeyComd::Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent)
    {
    ///Function which appends 1000 list-items in a QListWidget called "elements_listwidget" in my QDialog.
    }

    The usual flow is:
    
    1) i click an item(Carwash job) in Mainwindow
    2) the QDialog box shows-up,i press showbutton and list of 10000 possible employees show up
    3) i select an employee jack in QDialog and click okay.
    4) the Mainwindow item gets changed to "Car washing job assigned to: Jack, height 5'10, weight 86"
    
    My question is that in step-3 , even when entire 10000 elements are not loaded yet and i find my preferred employee in first 500 list items, i select it and click 'ok' on dialog box , the item in mainwindow still doesnt change until the thread3 finishes running, can i force stop or terminate thread3 ?? such that when i click okay thread3 stops, and the item in main window changes.
    
    This is my Dialog cpp file named Keycomd.cpp
    
    

    #include "KeyComd.h"
    #include "ui_KeyComd.h"
    #include <QtCore>
    #include <QtGui>
    #include <vector>
    #include<QDebug>
    #include "ExecutionContext.h"
    #include "XMLParser.h"
    #include "Logger.h"
    #include "BlockCommand.h"
    #include "UIAElementUtils.h"

    ExecutionContext exc;
    QStringList refreshed_elements;

    KeyComd::KeyComd(QWidget *parent)
    : QDialog(parent)
    {
    ui.setupUi(this);
    HRESULT hr = exc.init();
    }

    KeyComd::~KeyComd()
    {
    }
    void KeyComd::on_showbutton_clicked()
    {
    ui.elements_listwidget->clear();
    desktop_elements.clear();

    std::thread thread3(&KeyComd::Print_step, this); // Here it calls a thread, because of this thread ,the execution of "Print_Descendants_key" function happens in a separate thread from main thread
    thread3.detach();
    

    }

    void KeyComd::Print_step()
    {
    Print_Descendants_key(exc.pUIAutomation, nullptr, 0);
    }

    void KeyComd::Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent)
    {
    ///Function which appends 10000 list-items in a QListWidget called "elements_listwidget" in my QDialog.
    }

    
    my mainwindow.cpp code is
    

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "XMLParser.h"
    #include "ExecutionContext.h"
    #include "Logger.h"
    #include "BlockCommand.h"
    #include "UIAElementUtils.h"
    #include <thread>
    #include <iostream>
    #include <QtWidgets/qapplication.h>
    #include <QtCore>
    #include <QtGui>
    #include <sstream>
    #include <QtWidgets/qmessagebox.h>
    #include <QtWidgets/qlistwidget.h>
    #include <string>
    #include <string.h>
    #include <cstring>
    #include <chrono>
    #include <QCloseEvent>
    #include "Header.h"
    #include <map>
    #include <QtWidgets/qinputdialog.h>
    #include <vector>
    #include "dragsupport.h"
    #include "KeyComd.h"

    ExecutionContext exContext;

    using namespace std;

    MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    {
    populatemaps();
    ui->setupUi(this);

    HRESULT hr = CoInitializeEx(NULL, NULL);
    ExecutionContext exContext;
    hr = exContext.init();
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::on_xml_scripts_textbox_itemDoubleClicked(QListWidgetItem* item)
    {
    KeyComd keyComd;
    keyComd.exec();

        if (keyComd.result() == QDialog::Accepted) //when i click okay,the code inside this block gets executed
        {                   
           // Here when okay is clicked, i want to check if thread3 is still running and if it is then stop/terminate the thread3 which is in KeyComd.cpp file 
           
           ui->qlistwidget->additem("Car washing Job assigned to: Jack , height 5'10, weight 86, age 21");
        }
    

    }



  • Signals and slots, Mrs. Langdon, signals and slots.

    www.classicmoviehub.com - John Wayne quote

    And no, you shouldn't force-terminate a thread. You should build in preemption points that check for an exit flag and exit the thread function gracefully if the flag is set.


  • Qt Champions 2019

    @learnist Why does your dialog start a thread in the first place? Also, you are detaching from the thread: how do you want to check then whether it is running and stop it if it does? Do not detach and make the thread object member variable.



  • @jsulm Thanks sounds like that would would work. i changed it slightly but getting some errors

    is this what u are saying ??
    code for mainwindow.cpp

    #include <QThread>
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "XMLParser.h"
    #include "ExecutionContext.h"
    #include "Logger.h"
    #include "BlockCommand.h"
    #include "UIAElementUtils.h"
    #include <thread>
    #include <iostream>
    #include <QtWidgets/qapplication.h>
    #include <QtCore>
    #include <QtGui>
    #include <sstream>
    #include <QtWidgets/qmessagebox.h>
    #include <QtWidgets/qlistwidget.h>
    #include <string>
    #include <string.h>
    #include <cstring>
    #include <chrono>
    #include <QCloseEvent>
    #include "Header.h"
    #include <map>
    #include <QtWidgets/qinputdialog.h>
    #include <vector> 
    #include "dragsupport.h"
    #include "KeyComd.h"
    
    
    ExecutionContext exContext;
    
    using namespace std; 
    
    MainWindow::MainWindow(QWidget* parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        populatemaps();
        ui->setupUi(this);
     
        HRESULT hr = CoInitializeEx(NULL, NULL);
        ExecutionContext exContext;
        hr = exContext.init();
        QThread dialog_thread;
    }
    
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_xml_scripts_textbox_itemDoubleClicked(QListWidgetItem* item)
    {
            KeyComd keyComd;
            keyComd.moveToThread(&dialog_thread);
            connect(&keyComd, &QDialog::Accepted, &dialog_thread, &QThread::quit);
            dialog_thread.start();
            keyComd.exec();        
            
            if (keyComd.result() == QDialog::Accepted) //when i click okay,the code inside this block gets executed
            {                   
               // Here when okay is clicked, i want to check if thread3 is still running and if it is then stop/terminate the thread3 which is in KeyComd.cpp file 
               ui->qlistwidget->additem("Car washing Job assigned to: Jack , height 5'10, weight 86, age 21");   
               emit keyComd.accepted();
            }
    }
    

    code for dialogbox

    #include "KeyComd.h"
    #include "ui_KeyComd.h"
    #include <QtCore>
    #include <QtGui>
    #include <vector> 
    #include<QDebug>
    #include "ExecutionContext.h"
    #include "XMLParser.h"
    #include "Logger.h"
    #include "BlockCommand.h"
    #include "UIAElementUtils.h"
    
    ExecutionContext exc;
    QStringList refreshed_elements;
    
    KeyComd::KeyComd(QWidget *parent)
        : QDialog(parent)
    {
        ui.setupUi(this);
        HRESULT hr = exc.init();
    }
    
    KeyComd::~KeyComd()
    {
    }
    void KeyComd::on_showbutton_clicked()
    {
        ui.elements_listwidget->clear();
        desktop_elements.clear();
        this->Print_Descendants_key();
    }
    
    void KeyComd::Print_step()
    {
        Print_Descendants_key(exc.pUIAutomation, nullptr, 0);
    }
    
    void KeyComd::Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent)
    {
        ///Function which appends 10000 list-items in a QListWidget called "elements_listwidget" in my QDialog.
    }
    

    but i am getting an error in this line keyComd.moveToThread(&dialog_thread); saying identifier dialog_thread is undefined. in the mainwindow class.


  • Qt Champions 2019

    @learnist said in How can i stop a thread running in my Dialog Class from my mainWindow:

    QThread dialog_thread;

    ? This is a local variable in the constructor! Make it MEMBER variable...

    "saying identifier dialog_thread is undefined. in the mainwindow class" - of course it's undefined as you do not have such a member variable only a local variable in the constructor...



  • @jsulm Thanks for correcting me ,i tried making the thread member function, still it shows this error "Here its showing an error "call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type"

    for reference this is my.cpp file

    #include "KeyComd.h"
    #include "ui_KeyComd.h"
    #include <QtCore>
    #include <QtGui>
    #include <vector> 
    #include<QDebug>
    #include "ExecutionContext.h"
    #include "XMLParser.h"
    #include "Logger.h"
    #include "BlockCommand.h"
    #include "UIAElementUtils.h"
    
    ExecutionContext exc;
    QStringList refreshed_elements;
    
    KeyComd::KeyComd(QWidget *parent)
    	: QDialog(parent)
    {
    	ui.setupUi(this);
    	HRESULT hr = exc.init();	
    }
    
    KeyComd::~KeyComd()
    {
    }
    void KeyComd::on_showbutton_clicked()
    {
    	ui.elements_listwidget->clear();
    	desktop_elements.clear();
    
    	thread3(&KeyComd::Print_step, this); // Here its showing an error "call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type"
    	thread3.detach(); //should i not detach here ???
    }
    
    void KeyComd::Print_step()
    {
    	Print_Descendants_key(exc.pUIAutomation, nullptr, 0);
    }
    
    void KeyComd::Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent)
    {
    	///Function which appends 1000 list-items in a QListWidget called "elements_listwidget" in my QDialog.
    }
    
    
    
    
    void KeyComd::closeEvent(QCloseEvent* event)
    {
    	std::terminate();
    }
    
    void KeyComd::accepted()
    {
    	std::terminate();
    }
    

    This is my .h file

    #pragma once
    
    #include<QtWidgets/qdialog.h>
    #include "ui_KeyComd.h"
    #include <thread>
    #include "ExecutionContext.h"
    #include "XMLParser.h"
    #include "Logger.h"
    #include "BlockCommand.h"
    #include "UIAElementUtils.h"
    
    class KeyComd : public QDialog, public Ui::KeyComd
    {
    	Q_OBJECT
    	
    public:
    	KeyComd(QWidget *parent = Q_NULLPTR);
    	~KeyComd();
    
    	std::thread thread3; //Here i am creating it as a member variable.
    	
    	std::thread *thread3; //have even tried this, still it shows an error.
    
    
    	void Print_step();
    
    	void closeEvent(QCloseEvent* event);
    	void accepted();
    	void Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent = 0);
    	QString PrintElement_Info_key(IUIAutomationElement* pElement);
    
    private slots:
    	void on_showbutton_clicked();
    
    	void on_buttonBox_accepted();
    	
    private:
    
    
    
    	QStringList desktop_elements;
    
    	Ui::KeyComd ui;
    };
    
    

  • Qt Champions 2019

    @learnist said in How can i stop a thread running in my Dialog Class from my mainWindow:

    thread3(&KeyComd::Print_step, this);

    What is this line supposed to do? This is not valid C++ code as std::thread does not have an operator() operator.
    Initialisation is done in constructors:

    KeyComd::KeyComd(QWidget *parent)
    	: QDialog(parent),
              thread3(&KeyComd::Print_step, this)
    {
    	ui.setupUi(this);
    	HRESULT hr = exc.init();	
    }
    

    "//should i not detach here ???" - why?



  • @learnist please don't double post.