Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Shared Memory and Threads

Shared Memory and Threads

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 353 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    GaetanDesrues
    wrote on last edited by
    #1

    Hi everyone !

    I'm trying to launch my application on 2 threads : 1 for reading and 1 for writing.
    On a gui, I have a slider (input) and a lcdNumber (output). I want the slider to write its value somewhere and, on another thread, read this same value to be displayed on the lcdnumber.

    Here is the code :

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QLCDNumber>
    #include <QSlider>
    #include <QThread>
    #include <QDebug>
    
    namespace Ui {
    class MainWindow;
    }
    
    template<typename T>
    class Obj : public QThread
    {
        virtual void run()=0;
    protected:
        int* _m;
        T* _s;
    public:
        Obj(T* s, int* m) : _m(m), _s(s){ }
    };
    
    class Slid : public Obj<QSlider>
    {
        void run() override;
    public:
        Slid(QSlider* s, int* m) : Obj<QSlider>(s,m) {}
    };
    
    class Lcd : public Obj<QLCDNumber>
    {
        void run() override;
    public:
        Lcd(QLCDNumber* s, int* m) : Obj<QLCDNumber>(s,m) {}
    };
    
    
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
        void start()
        {
            Slid *sldt = new Slid(sli, &_m);
            connect(sldt, &Slid::finished, sldt, &QObject::deleteLater);
            sldt->start();
    
            Lcd *lcdt = new Lcd(lcd, &_m);
            connect(lcdt, &Lcd::finished, lcdt, &QObject::deleteLater);
            lcdt->start();
        }
    private:
        Ui::MainWindow *ui;
        QSlider* sli;
        QLCDNumber* lcd;
        int _m;
    };
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow), _m(0)
    {
        ui->setupUi(this);
    
        sli = ui->verticalSlider;
        lcd = ui->lcdNumber;
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
        delete sli;
        delete lcd;
    }
    
    
    void Slid::run()
    {
        for(;;) *_m = _s->value();
    }
    
    void Lcd::run()
    {
        for(;;) _s->display(*_m);
    }
    

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        MainWindow w;
        w.show();
        w.start();
    
        return a.exec();
    }
    

    The code is compiling pretty well and it works (I can see the lcdnumber changing while I'm modifying the slider). The problem is that this connection stops after few seconds, one of the 2 objects freezes on the screen.

    Is it the good way to run a qt app on 2 threads ? Is there a better way to share memory ?

    Thank you for any advice on this issue,
    Gaetan

    1 Reply Last reply
    0
    • Gojir4G Offline
      Gojir4G Offline
      Gojir4
      wrote on last edited by
      #2

      Hi @GaetanDesrues ,
      Is there a particular reason for using threads ?
      If you need to display value of slider on lcd widget, you can do it with signal-slots with only one line of code.

      MainWindow::MainWindow(QWidget *parent) :
          QMainWindow(parent),
          ui(new Ui::MainWindow), _m(0)
      {
          ui->setupUi(this);
          //using qOverload requires "CONFIG += c++14" in the pro file, otherwise use "QOverload" alternative with c++11
          connect(ui->verticalSlider, &QSlider::valueChanged, ui->lcdNumber, qOverload<int>(&QLCDNumber::display));
      }
      

      I see several reasons for your app to freeze, first because you access GUI element from thread, which must be avoided, you need to use signal-slots for that.
      Also you are destroying sli and lcd in your MainWindow destructor which will also probably cause a crash when you close the app. You don't need to delete them as they are children of ui and are deleted when delete ui is called.

      1 Reply Last reply
      4

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved