Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. [Solved] Random number generator with a time interval
Forum Updated to NodeBB v4.3 + New Features

[Solved] Random number generator with a time interval

Scheduled Pinned Locked Moved C++ Gurus
17 Posts 3 Posters 10.8k Views 1 Watching
  • 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.
  • L Offline
    L Offline
    lindmccam
    wrote on last edited by
    #1

    Hello,

    I am new to this forum and still pretty new at using the Qt program, so please be patient with me. I am working on a program that after a certain amount of time a new random number appears on the GUI. How I want it is that when a button is pressed within the GUI, the random number generator starts and displays its first random number. Once a certain amount of time has passed (lets say 15 secs), a new random number is then displayed within the GUI. I have gotten a suggestion of using a timer interrupt within the program, but I am having a hard time finding a decent example of it. I am not an advanced programmer, so please once again, be patient with me. I really do appreciate all the help. Thank you very much for any type of advice.

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      Hi and welcome to DevNet.

      What you need is a "QTimer":http://qt-project.org/doc/qt-5/QTimer.html#details, and a slot in your class that will regenerate a number. For basic random number generation, you can use "qRand":http://qt-project.org/doc/qt-5/qtglobal.html#qrand.

      If anything is still unclear, please ask :)

      (Z(:^

      1 Reply Last reply
      0
      • L Offline
        L Offline
        lindmccam
        wrote on last edited by
        #3

        Thank you for the advice. I have been looking into the QTimer function for a while today and I am still confused on how to use the "connect(timer,SIGNAL(timeout()),this,SLOT())" function. The main part about it is I am unsure about what I need to put in the "SLOT" section. I would like my GUI to have it when the button is pressed the first random number is displayed on the label, then a certain amount of time goes by, then another random number is displayed. The only way to get out of that loop is by clicking the button again. That is why I thought I would have to put clicked() for the SLOT section. But it did not work. A message would come up saying no such slot MainWindow::clicked() in...

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          Slot is a method you create yourself in your code (although, of course, some Qt classes have some convenient slots prepared) that reacts to a signal in a way you desire. A detailed description can be found "here":http://qt-project.org/doc/qt-5/signalsandslots.html but it can be hard to grasp for a newbie. I'll try to explain it in a bit simpler manner.

          So, your QTimer will emit a signal (timeout) every few seconds. What you want to do is to then get a new random number, and update the label. To achieve this, you should add a slot in your code:
          @
          // MainWindow.h
          private slots:
          void updateRandomNumber();
          // your timer:
          QTimer timer;

          // MainWindow.cpp
          void MainWindow::updateRandomNumber()
          {
          ui->myLabel->setText(QString::number(qRand()));
          }

          // signal and slot connection. You probably do it in your button clicked slot
          void MainWindow::on_pushButton_clicked()
          {
          if (timer.isActive()) {
          timer.stop(); // timer will stop if you click the button again
          } else {
          connect(&timer, SIGNAL(timeout()), this, SLOT(updateRandomNumber()));
          timer.start(1000);
          }
          }
          @

          (Z(:^

          1 Reply Last reply
          0
          • L Offline
            L Offline
            lindmccam
            wrote on last edited by
            #5

            I will defiantly try this. I was getting confused on where I should put the information for the QTimer class. I was putting that information in my .cpp instead of my .h. In doing that, does that answer the question into why the "redefinition" and "previous" class type errors kept on popping up every time I would build my GUI?

            1 Reply Last reply
            0
            • sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #6

              I don't know. I have not seen your code, or the errors you mention. I can guess if you want me to ;)

              (Z(:^

              1 Reply Last reply
              0
              • L Offline
                L Offline
                lindmccam
                wrote on last edited by
                #7

                I will first add your suggestions into my code. If I am still having trouble, I will post my code on there. Please do not laugh or judge me too much on it when you see it. I am not a pro at programming. Please be patient with me. Once again, thank you so much for giving me pointers when dealing with this code.

                1 Reply Last reply
                0
                • sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #8

                  Hey, don't worry! :-) I may be harsh at times, but I do understand that you are learning and everything is tricky for you. I used to be a newbie, too.

                  (Z(:^

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    lindmccam
                    wrote on last edited by
                    #9

                    I have input your suggestions in my mainwindow.h file and mainwindow.cpp, but every time I click the pushButton the first time, the GUI exits unexpectedly instead of start the RNG. Below is my code:
                    @//mainwindow.h
                    namespace Ui
                    {
                    class MainWindow;
                    }

                    class MainWindow:public QMainWindow
                    {

                    Q_OBJECT

                    public:

                    explicit MainWindow(QWidget *parent = 0);

                    ~MainWindow();

                    private slots:

                    void on_pushButton_clicked();

                    void updateRandomNumber();

                    private:

                    Ui::MainWindow *ui;

                    QTimer *timer;

                    };

                    #endif // MAINWINDOW_H

                    //MainWindow.cpp

                    MainWindow::MainWindow(QWidget *parent) :

                    QMainWindow(parent),

                    ui(new Ui::MainWindow)

                    {

                    ui->setupUi(this);

                    ui->max->setValidator(new QIntValidator(0,100000000));

                    ui->min->setValidator(new QIntValidator(0,100000000));

                    }

                    MainWindow::~MainWindow()

                    {

                    delete ui;
                    }

                    void MainWindow::updateRandomNumber()

                    {

                    int high = ui->max->text().toInt();

                    int low = ui->min->text().toInt();

                    qsrand((unsigned)time(0));

                    ui->label->setText(QString::number(qrand()%((high + 1) - low) + low));

                    }

                    //Control timer with the pushButton. RNG should activate.

                    void MainWindow::on_pushButton_clicked()
                    {
                    if(timer->isActive())

                    {

                    connect(timer,SIGNAL(timeout()),this,SLOT(updateRandomNumber()));

                    timer->start(15000);

                    }

                    else

                    {

                    timer->stop();//timer will stop if you click button again.

                    }

                    }
                    @

                    At first I kept your suggestion and had the "connect" function after the else statement, but it was still exiting out the program unexpectedly. I wanted the user to input their min and max value within the GUI and the random values stay within those values. Do you have any suggestions on why it keeps kicking me out of the GUI after I press the pushButton? Thank you once again for your help.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      lindmccam
                      wrote on last edited by
                      #10

                      Okay, I did a practice code on getting the timer and random number generator to be in sync. That came out fine. Once the pushButton is pressed, the RNG starts with the delay timer I asked for, but after I press the button again, it does not want to stop the RNG even though I have the disconnect command inputted in my code. Any suggestions on why this is would be lovely :) Below is my code. Thank you once again for your help Mr. sierdzio.

                      @
                      //mainwindow.cpp
                      #include "mainwindow.h"
                      #include "ui_mainwindow.h"
                      #include "cstdlib"
                      #include "stdlib.h"
                      #include "string"
                      #include "QTimer"
                      #include "QObject"

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

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

                      void MainWindow::updateRandomNumber()
                      {
                      qsrand((unsigned)time(0));
                      ui->label->setText(QString::number(qrand()));
                      }

                      void MainWindow::on_pushButton_clicked()
                      {
                      QTimer *timer = new QTimer(this);
                      if(timer->isActive())
                      {
                      QObject::disconnect(this,SLOT(updateRandomNumber(void)));
                      //delete updateRandomNumber;
                      timer->stop();//timer will stop if you click the button again.
                      }
                      else
                      {
                      connect(timer,SIGNAL(timeout()),this,SLOT(updateRandomNumber()));
                      timer->start(1000);
                      }
                      }

                      @

                      1 Reply Last reply
                      0
                      • sierdzioS Offline
                        sierdzioS Offline
                        sierdzio
                        Moderators
                        wrote on last edited by
                        #11

                        You have not initialised the timer, so the program segfaults. You declare it as a pointer, but newer call this:
                        @
                        timer = new QTimer;
                        @

                        The best place to do it is the constructor. A decent compiler should have warned you about this, too.

                        (Z(:^

                        1 Reply Last reply
                        0
                        • sierdzioS Offline
                          sierdzioS Offline
                          sierdzio
                          Moderators
                          wrote on last edited by
                          #12

                          Oh, it seems we have been writing a post in parallel :)

                          You are initialising the timer in wrong place! Every time you click a button, you create a new QTimer. This is a bad memory leak, and will not work as intended. Move the initialisation to the constructor:
                          @
                          MainWindow::MainWindow(QWidget *parent) :
                          QMainWindow(parent),
                          ui(new Ui::MainWindow)
                          {
                          ui->setupUi(this);
                          QTimer *timer = new QTimer(this);
                          }
                          @

                          (Z(:^

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            lindmccam
                            wrote on last edited by
                            #13

                            when I moved it to
                            @
                            MainWindow::MainWindow(QWidget *parent) :
                            QMainWindow(parent),
                            ui(new Ui::MainWindow)
                            {
                            ui->setupUi(this);
                            QTimer *timer = new QTimer(this);
                            }
                            @

                            It would exit out of the GUI unexpectedly after I push the pushButton. But once it is back under

                            @
                            void MainWindow::on_pushButton_clicked()
                            {
                            QTimer *timer = new QTimer(this);
                            @

                            The GUI does not exit out, the RNG timer works after I press the pushButton for the first time, but the RNG timer will not stop once the pushButton is pressed for a second time. Thank you for your help and your patience. It is greatly appreciated.

                            1 Reply Last reply
                            0
                            • sierdzioS Offline
                              sierdzioS Offline
                              sierdzio
                              Moderators
                              wrote on last edited by
                              #14

                              Sorry, I made a small mistake. My previous snippet should have been:
                              @
                              MainWindow::MainWindow(QWidget *parent) :
                              QMainWindow(parent),
                              ui(new Ui::MainWindow)
                              {
                              ui->setupUi(this);
                              timer = new QTimer(this);
                              }
                              @

                              As you see, no "QTimer *". This is because we want to initialise the timer present in the header file, and not a completely new one. You can also move the connect statement to the constructor, and remove the disconnect statement - it should still work correctly.

                              (Z(:^

                              1 Reply Last reply
                              0
                              • L Offline
                                L Offline
                                lindmccam
                                wrote on last edited by
                                #15

                                IT WORKS!!!! thank you so much. I am going to add some stuff to my GUI and I have a feeling you will be hearing from you again lol. Thank you once again for your help.

                                1 Reply Last reply
                                0
                                • sierdzioS Offline
                                  sierdzioS Offline
                                  sierdzio
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  You are welcome, I'm glad to hear it works. Happy coding!

                                  (Z(:^

                                  1 Reply Last reply
                                  0
                                  • A Offline
                                    A Offline
                                    abstract
                                    wrote on last edited by
                                    #17

                                    @
                                    Line 82 (qrand()%((high + 1) - low) + low) )
                                    @

                                    Is not a very good method to generate random numbers within a given range. (In fact it's very very bad for most generators )

                                    You are assuming that the low-order bits from the generator are uniformly distributed . This is not the case with most generators. In most generators the randomness occurs in the high order bits.

                                    By using the remainder after divisions you are in effect throwing out the randomness.

                                    You should scale using multiplication and division. Not using the modulo operator.
                                    eg
                                    @
                                    my_number= start_required + ( generator_output * range_required)/generator_maximum;

                                    if generator_output is in [0, generator_maximum]
                                    my_number will be in [start_required , start_required + range_required]
                                    @

                                    1 Reply Last reply
                                    0

                                    • Login

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