Qthreads or signal and slot with Qtimer or class



  • I'm trying to create a LCD that displays a number base off my cpu calculations. I dont know if i should make a Qthread or signal and slot with qtimer or just pass the display to a signal and emit it.

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_2_pressed();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "common/cpu_usage.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_2_pressed()
    {
        Cpu_Usage cpu_display;
        ui->lcdNumber->setPalette(Qt::black);
        ui->lcdNumber->display(cpu_display.Cpu_Usage_Calculate());
        ui->lcdNumber->show();
    }
    

    cpu_usage.h

    #ifndef CPU_USAGE_H
    #define CPU_USAGE_H
    
    #include "../mainwindow.h"
    
    #include <QObject>
    
    class Cpu_Usage : public QWidget
    {
    	Q_OBJECT
    public:
        Cpu_Usage(QWidget *parent = 0);
    	~Cpu_Usage();
    
    	//CPU
    	CHAR Cpu_Usage_Calculate();
        void GetSystemTimesAddress();
    
    signals:
    
    public slots :
    
    private:
    
    };
    
    #endif // CPU_USAGE_H
    

    cpu_usage.cpp

    #include "cpu_usage.h"
    #include "../ui_mainwindow.h"
    #include "../mainwindow.h"
    
    //CPU
    typedef BOOL(__stdcall * pfnGetSystemTimes)(LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime);
    static pfnGetSystemTimes s_pfnGetSystemTimes = NULL;
    static HMODULE s_hKernel = NULL;
    
    // Constructor
    Cpu_Usage::Cpu_Usage(QWidget *parent) : QWidget(parent)
    {
    
    }
    
    Cpu_Usage::~Cpu_Usage()
    {
    
    }
    
    void Cpu_Usage::GetSystemTimesAddress()
    {
    	if (s_hKernel == NULL)
    	{
    		s_hKernel = LoadLibrary(L"Kernel32.dll");
    		if (s_hKernel != NULL)
    		{
    			s_pfnGetSystemTimes = (pfnGetSystemTimes)GetProcAddress(s_hKernel, "GetSystemTimes");
    			if (s_pfnGetSystemTimes == NULL)
    			{
    				FreeLibrary(s_hKernel); s_hKernel = NULL;
    			}
    		}
    	}
    }
    
    CHAR Cpu_Usage::Cpu_Usage_Calculate()
    {
        GetSystemTimesAddress();
    	FILETIME               ft_sys_idle;
    	FILETIME               ft_sys_kernel;
    	FILETIME               ft_sys_user;
    
    	ULARGE_INTEGER         ul_sys_idle;
    	ULARGE_INTEGER         ul_sys_kernel;
    	ULARGE_INTEGER         ul_sys_user;
    
    	static ULARGE_INTEGER    ul_sys_idle_old;
    	static ULARGE_INTEGER  ul_sys_kernel_old;
    	static ULARGE_INTEGER  ul_sys_user_old;
    
    	CHAR  usage = 0;
    
    	s_pfnGetSystemTimes(&ft_sys_idle,
    		&ft_sys_kernel,
    		&ft_sys_user);
    
    	CopyMemory(&ul_sys_idle, &ft_sys_idle, sizeof(FILETIME));
    	CopyMemory(&ul_sys_kernel, &ft_sys_kernel, sizeof(FILETIME));
    	CopyMemory(&ul_sys_user, &ft_sys_user, sizeof(FILETIME));
    
    	usage =
    		(
    		(
    			(
    			(
    				(ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart) +
    				(ul_sys_user.QuadPart - ul_sys_user_old.QuadPart)
    				)
    				-
    				(ul_sys_idle.QuadPart - ul_sys_idle_old.QuadPart)
    				)
    			*
    			(100)
    			)
    			/
    			(
    			(ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart) +
    				(ul_sys_user.QuadPart - ul_sys_user_old.QuadPart)
    				)
    			);
    
    	ul_sys_idle_old.QuadPart = ul_sys_idle.QuadPart;
    	ul_sys_user_old.QuadPart = ul_sys_user.QuadPart;
    	ul_sys_kernel_old.QuadPart = ul_sys_kernel.QuadPart;
    
    	return usage;
    }
    

    So right now if i click the button it displays the numbers in the lcd screen. I am trying to make it so that i dont have to click the mouse but it will just run on its own.

    Methods ideas i've come up with:

    A few methods i've come up with is connecting a timeout timer while passing the ui->lcdnumber the signal being the call to Cpu_Usage_Calculate() and the slot being the display to the ui lcdnumber.

    Another method would be craete a qthread in the cpu_usage constructor make a connecting singal with lcdnumber UI.

    What method should i use? Any examples or ideas woould be helpfull.

    // hook the signal directly to the lcdnumber
    Cpu_Usage  Cpu_Display;
     connect(Cpu_Display, SIGNAL(displayMsg()), ui->lcdnumber, SLOT(display(Cpu_Display.Cpu_Usage_Calculate())));
    

    then just emit a signal?



  • @Sunfluxgames Well assuming you want real time tracking of the cpu you will want that calculation to run on a timer, say every second. So you should put that in a thread with a 1s sleep. Then from that thread you just emit an update signal to the gui and it updates the display.



  • Should I put the thread inside the mainwindow contructor? Or build it from the other class? Should i use Qthread with a signal.

    Should i build the timer with a signal and slot that timesouts. got a small example or something? Should i send the emit on the mainwindow GUI

    create a thread inside the cpu class with a 1 sec sleep connect a timer that times out then setup a signal to update the display UI

    create a object on the heap (mainwindow constructor) and pass the run fucntion or conctructor that buils the thread and timer?



  • @Sunfluxgames So yea, just use a QTimer with an interval of say 1 second. That will kick off your threaded cpu calc function. You can create the QThread from wherever including the mainwindow. Or you could move the CPU stuff to a class derived from QObject and then use moveToThread on it.

    I would make the CPU stuff a class, then you can have a signal in it for the update. It's also nice and easy for using moveToThread on that object. Then when you start it up in the thread, just connect a timer with 1s or whatever interval you want to kick it off.. after calculation emit your signal that your lcd window catches and updates.

    I don't have an example and it would take a few to write that up but if you're really confused I could do it tomorrow.



  • sure would love to see a small example.

    the singal and slot for display with emit is pretty simple.

    the Qtimer with a timeout and a fucntion that loops thru the cpu class..

    void Cpu_Usage::displaySignal(double num)
    {
          emit DisplayMsg( num );
    }
    
    void DisplayMsg(double num);
    
    //connect the display
    Cpu_Usage *cpu_usage_instance = new Cpu_Usage(this);
    connect(cpu_usage_instance, SIGNAL(DisplayMsg(()), ui->lcdNumber, SLOT(display()));
    
    // Timer
    timer = new  Qtimer(this);
    connect(timer, SIGNAL(timeout(()), this, SLOT(StartDisplay()));
    timer->start(100);
    
    void Cpu_Usage::StartDisplay()
    {
             GetSystemTimesAddress();
             displaySignal(CHAR Cpu_Usage_Calculate());
    }
    

    Think thats all i need wrote this off the top of my head.. Sorry if it looks like junk..


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.