Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

QFutureWatcher signal not working



  • Hi, Im trying to use QtConcurrent::run to run one of my function in another thread
    I use this code for doing this

    int getID(const char * str)
    {
    	DWORD ID = 0;
    	while (!PID)
    	{
    		ID = example(str);
    		Sleep(30);
    	}
    	return ID;
    }
    
    void mainw::on_pushButton_clicked() //Start Injector and game
    {
    	const char* szP = "something";
    
    	QFutureWatcher<int> watcher;
    	connect(&watcher, &QFutureWatcher<int>::finished, this, &mainw::After_PID);
    
    	QThreadPool pool;
    	QFuture<int> future = QtConcurrent::run(getID, szP);
    	watcher.setFuture(future);
    	//QString result = future.result();
    
    //after that I also want to get output of getProcID return in this function too
    int mainw::After_PID(int pid)
    {
    	if (pid != 0)
    	{
    		ui.textBrowser->append("Process Founded: " + pid);
                    //some other code
    	}
    	return 0;
    }
    

    my code have lots of problem, but my main problem is why watcher signal doesn't work?
    (for test I remove all arg from After_PID and tried to simple only print a text for test, but its wont work)
    so I want to know

    1. how can I get watcher signal to work
    2. how can I get getID return value in After_PID

  • Lifetime Qt Champion

    No, you need to only create it once, in the constructor. Giving it a parent means that it will be destroyed alongside its parent however you will still create new objects every time and thus fill the memory until the parent destruction.


  • Lifetime Qt Champion

    Hi,

    There's no signal because your watcher lifetime ends with the end of the method it's created in.



  • @SGaist said in QFutureWatcher signal not working:

    Hi,

    There's no signal because your watcher lifetime ends with the end of the method it's created in.

    thank you for fast answer, so you saying I need to declare it some where else? (maybe global in cpp?
    and one other thing, how can I get return of getID (maybe declare both watcher and future outside of this method? but where is best place and what is best way to do it?)



  • @saeid0034 Take a look at my posts.

    I am following this tutorial

    https://www.bogotobogo.com/Qt/Qt5_QtConcurrent_QFutureWatcher_QProgressDialog_map.php

    which covers in principle using several Qt classes to accomplish the "delay".
    The tutorial is very sketchy, it does not explain well what is going on ( in sequence) and assumes much. There are few unpublished "default" values in use.

    The tutorial is OK but it needs to be implemented very carefully- step by step - also due to few time issues.


  • Lifetime Qt Champion

    @saeid0034 said in QFutureWatcher signal not working:

    maybe global in cpp

    Not global, but as member variable in your mainw class.



  • @jsulm said in QFutureWatcher signal not working:

    @saeid0034 said in QFutureWatcher signal not working:

    maybe global in cpp

    Not global, but as member variable in your mainw class.

    thank you
    I use this code
    in mainw header file

    class mainw : public QMainWindow
    {
        Q_OBJECT
    
    public:
        mainw(QWidget *parent = Q_NULLPTR);    
    
    private slots:
        void on_pushButton_3_clicked();
        void load_change(int index);
        void on_pushButton_clicked();
        int After_PID();
    
    private:
        Ui::mainw ui;
        QFutureWatcher<int> *watcher;
        QFuture<int> *future;
    };
    

    and in mainw cpp

    void mainw::on_pushButton_clicked() //Start Injector and game
    {
    	const char* szP = "something";
    
    	watcher = new QFutureWatcher<int>;
    	future = new QFuture<int>;
    	
    	connect(watcher, &QFutureWatcher<int>::finished, this, &InjectorGUI::After_PID);
    	connect(watcher, &QFutureWatcher<int>::finished, watcher, &QFutureWatcher<int>::deleteLater);
    
    	QThreadPool pool;
    	QFuture<int> future = QtConcurrent::run(getProcID, szProc);
    	watcher->setFuture(future);
    	//QString result = future.result();
    }
    

    now its working and after receive finished signal After_PID opened.
    thanks about that
    know only thing I want to know is how can I get out put in After_PID?
    -edit-
    never mind after read qfuturewatcher document i find out I can use watcher->result();


  • Lifetime Qt Champion

    Note that you are now leaking QFutureWatcher objects each time you call that function.

    There's no need to recreate it each time.



  • @SGaist said in QFutureWatcher signal not working:

    Note that you are now leaking QFutureWatcher objects each time you call that function.

    There's no need to recreate it each time.

    thank you, so I need to add QFutureWatcher<int> *watcher = new QFutureWatcher<int>(this); instead of QFutureWatcher<int> *watcher; to header and remove watcher = new QFutureWatcher<int>; from source? right


  • Lifetime Qt Champion

    No, you need to only create it once, in the constructor. Giving it a parent means that it will be destroyed alongside its parent however you will still create new objects every time and thus fill the memory until the parent destruction.


Log in to reply