Results 1 to 7 of 7

Thread: Correct usage of QThread

  1. #1
    Join Date
    Nov 2010
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Correct usage of QThread

    Hi, I'm developing a qt application that interfaces with an external hardware device. My application consists of just 2 start/stop buttons and a listwidget used to display data received from the device. Since the data acquisition from the device requires me to call a blocking function, I've decided to put the call in a separated thread because data acquisition can be stopped only by calling another function from another thread. So I've created this QThread subclass:

    Qt Code:
    1. class InventoryThread : public QThread
    2. {
    3. Q_OBJECT
    4.  
    5. private:
    6. int handle;
    7. RFID_18K6C_INVENTORY_PARMS * inventoryParms;
    8. RFID_18K6C_INVENTORY_PARMS * SetInventoryParams(const RFID_RADIO_HANDLE handle, const int cycles);
    9.  
    10. public:
    11. explicit InventoryThread(QObject *parent = 0, int h = 0);
    12.  
    13. protected:
    14. void run();
    15.  
    16. signals:
    17.  
    18. public slots:
    19.  
    20. };
    To copy to clipboard, switch view to plain text mode 

    The relevant implementation is this:

    Qt Code:
    1. InventoryThread::InventoryThread(QObject *parent, int h) :
    2. QThread(parent)
    3. {
    4. handle = h;
    5. }
    6.  
    7. void InventoryThread::run()
    8. {
    9. RFID_18K6CTagInventory(handle, SetInventoryParams(handle, 5), 0);
    10. }
    To copy to clipboard, switch view to plain text mode 

    The main window code will call InventoryThread::start() when I click on the start button, then RFID_18K6CTagInventory will be called (which is a blocking function). This function can be stopped only by calling RFID_RadioCancelOperation in the main thread. Now, I'm not sure if my approach is correct, the documentation about QThread its main loop il pretty confusing.

    What should I do?

  2. #2
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

  3. #3
    Join Date
    Nov 2010
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Correct usage of QThread

    Ok, that clarified some things. I'm still having a little issue. My classes look as follows:

    Qt Code:
    1. class InventoryThread : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. private:
    6. int handle;
    7. QListWidget * list;
    8. RFID_18K6C_INVENTORY_PARMS * inventoryParms;
    9. RFID_18K6C_INVENTORY_PARMS * SetInventoryParams(const RFID_RADIO_HANDLE handle, const int cycles);
    10. QTimer * timer;
    11.  
    12. public:
    13. explicit InventoryThread(QObject *parent = 0, int h = 0, QListWidget *lst = 0);
    14.  
    15. signals:
    16.  
    17. public slots:
    18. void DoInventory();
    19. };
    20.  
    21. InventoryThread::InventoryThread(QObject *parent, int h, QListWidget * lst) : QObject(parent)
    22. {
    23. handle = h;
    24. list = lst;
    25. timer = new QTimer(this);
    26. list->connect(timer,SIGNAL(timeout()),SLOT(clear()));
    27. //connect(timer,SIGNAL(timeout()),list,SLOT(clear()));
    28. timer->setSingleShot(false);
    29. timer->start(1500);
    30. }
    31.  
    32. void InventoryThread::DoInventory()
    33. {
    34. printf("Doing inventory\n");
    35. RFID_18K6C_INVENTORY_PARMS * parms = SetInventoryParams(handle, 5);
    36. printf("Tag Inventory returned %d\n", RFID_18K6CTagInventory(handle, parms, 0));
    37. free(parms);
    38. }
    To copy to clipboard, switch view to plain text mode 
    In my main class I have
    Qt Code:
    1. class QThreadEx : public QThread
    2. {
    3. protected:
    4. void run() { exec(); }
    5. };
    6.  
    7. MainWindow::MainWindow(QWidget *parent) :
    8. QMainWindow(parent),
    9. ui(new Ui::MainWindow)
    10. {
    11. ui->setupUi(this);
    12. QObject::connect(this->ui->start,SIGNAL(clicked()),this,SLOT(StartInventory()));
    13. invThread = new InventoryThread(0, handle, this->ui->listWidget);
    14. thr = new QThreadEx();
    15. invThread->moveToThread(thr);
    16. invThread->connect(thr,SIGNAL(started()),SLOT(DoInventory()));
    17. }
    To copy to clipboard, switch view to plain text mode 

    Finally, when I click on my start button I call thr->start() and when I click on the end button I call thr->quit(). This scheme works only for the first time. If I click on the start button again the thread will not launch (I can't see the printf's output on my terminal). Obviously I'm still missing something. How can I launch again my thread after quitting it (or after DoInventory() slot ended its work)?

  4. #4
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Correct usage of QThread

    Rename InventoryThread to InventoryWorker or something similar.
    You really don't need QThreadEx.

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6.  
    7. invThread = new QThread(this);
    8. worker = new InventoryWorker; // parent is forbidden here
    9. worker->moveToThread(invThread);
    10. connect(ui->start,SIGNAL(clicked()),
    11. invThread, SIGNAL(startTimer())); // add slot startTimer in InventoryWorker
    12. invThread->start();
    13. }
    14.  
    15. MainWindow::~MainWindow() {
    16. worker->deleteLater();
    17. invThread->terminate();
    18. invThread->waitFor(3000);
    19. }
    20.  
    21. InventoryWorker::InventoryWorker(QObject *parent, int h, QListWidget * lst) : QObject(parent)
    22. {
    23. handle = h;
    24. list = lst;
    25. timer = new QTimer(this);
    26. list->connect(timer,SIGNAL(timeout()),SLOT(clear()));
    27. connect(timer,SIGNAL(timeout()),list,SLOT(clear()));
    28. timer->setSingleShot(false);
    29. }
    30.  
    31. InventoryWorker::startTimer() {
    32. timer->start(1500);
    33. }
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Nov 2010
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Correct usage of QThread

    How does your code call InventoryWorker:: DoInventory()? To put it simply what I need is:

    every time ui->start emits clicked() then run InventoryWorker:: DoInventory() in a different thread

  6. #6
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Correct usage of QThread

    This code I gave you is not complete. I wrote it just to show you a pattern. I don't know what you code do I don't need to.

  7. #7
    Join Date
    Nov 2010
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Correct usage of QThread

    Ok, after reading it twice I got it. Tank you all, you've been really helpful

Similar Threads

  1. Is this sentence correct?
    By SWEngineer in forum Newbie
    Replies: 6
    Last Post: 21st June 2011, 01:56
  2. Replies: 1
    Last Post: 9th May 2011, 13:16
  3. QThread 100% cpu usage on linux only
    By essial in forum Qt Programming
    Replies: 6
    Last Post: 26th April 2010, 15:33
  4. QThread usage and exec()
    By smahnken in forum Qt Programming
    Replies: 10
    Last Post: 24th August 2008, 18:13
  5. CPU Time & Memory Usage in QThread or QProcess
    By Davidaino in forum Qt Programming
    Replies: 0
    Last Post: 11th July 2008, 19:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.