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. [solved] adding Qt to existing program
Forum Updated to NodeBB v4.3 + New Features

[solved] adding Qt to existing program

Scheduled Pinned Locked Moved General and Desktop
45 Posts 6 Posters 22.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.
  • Z Offline
    Z Offline
    ZapB
    wrote on last edited by
    #15

    [quote author="mzimmers" date="1300743352"]

    I notice we had a few choices when we selected widget for our base class. What is a good working definition of a widget (for Qt purposes), and why did we choose it for this example?

    [/quote]

    QWidget is the base class of graphical elements of GUI applications. Technically you can also use other approaches but they are for later examples (QGraphicsView or QML if you want to read up on them).

    I chose QWidget here for simplicity so as not to muddy the waters with other facilities provided by QDialog or QMainWindow. QWidget keeps it as simple as it gets.

    [quote author="mzimmers" date="1300743352"]

    I don't really understand the syntax of widget.cpp, line 30. It appears you're making a new variable called s, but what does the first pair of parens contain? Is this some kind of compound function call?

    [/quote]

    As you say it creates a variable called "s". This is assigned a value constructed on the right hand side of the "=" operator. The construction uses the QString::arg() function. This allows you to specify a template string with placeholders "%1, %2, etc) which are then substituded fo the values in the .arg() function. So this line just substitutes in your computed value.

    [quote author="mzimmers" date="1300743352"]

    what controls the position and format of the output in the GUI window?

    [/quote]

    The position of th elabel within the window is determined by the layout that we assigned ot the form in design mode. The position of the window is determined by the window manager since we did not explicitly specify a position.

    The format of the string is determined by the way we constructed the variable "s" (see above).

    [quote author="mzimmers" date="1300743352"]

    if I wanted to add a pause button, how would I go about that? (this question is mostly out of curiosity, so don't spend a lot of time on it.)

    [/quote]

    As Volker said add a push button in design mode. Then make a connection from the QPushButton's "clicked()" signal to a slot in your Generator object that toggles the running of the timer.

    [quote author="mzimmers" date="1300743352"]

    can you explain the return a.exec(); in main.cpp? It seems like this is where the program spends all of its time, and I think I need to know more about this if I'm going to successfully decouple my main program from its auxiliary GUI.

    [/quote]

    Volkr has already explained this. This is where GUI programming differs from simple functional programming. In GUI's events are handled by the event loop which is encapsulated by the a.exec() call. No event loop would mean that nothing happens - including painting your GUI, generation of the timer events that drive your calculation etc.

    Nokia Certified Qt Specialist
    Interested in hearing about Qt related work

    1 Reply Last reply
    0
    • mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #16

      OK, I'm back. (Had to chase down some bugs for a couple of days.)

      So, regarding this "event loop" -- it seems to be a member function of QWidget, right? I'm curious...what throttles it? I assume it doesn't just run open loop.

      Also...what happens to my main()? In my main, besides initializing some variables, I have a loop that calls a function. Does this functionality become a function that is passed to the event loop by a connect()?

      Let's say I just want to imbed my current program into a Qt application. For right now, I don't even need to create a GUI; I just want to get my program logic contained within the Qt constructs. Do I create a loop function, and use a connect() call to access it?

      And...what's the best source of online documentation for this? The help stuff in Creator seems to have some dead links.

      Thanks.

      1 Reply Last reply
      0
      • G Offline
        G Offline
        goetz
        wrote on last edited by
        #17

        It's always the same answer: It depends :-)

        If it is a program without GUI components and if you do not use signal/slot connections within the existing code, it is very likely that you do not need an event loop.

        It would be helpful if you could describe what you want to do by embedding the existing code into a Qt application environment.

        Some reading about events and the event loop is in:

        • "QCoreApplication Class Reference":http://doc.qt.nokia.com/4.7/qcoreapplication.html#exec
        • "QEventLoop Class Reference":http://doc.qt.nokia.com/4.7/qeventloop.html
        • "The Event System":http://doc.qt.nokia.com/4.7/eventsandfilters.html

        Signals/slots need a running event loop to work reliably.

        PS: If you stumble over dead links, please open a bug report, so that the Trolls can fix them for the next release.

        http://www.catb.org/~esr/faqs/smart-questions.html

        1 Reply Last reply
        0
        • G Offline
          G Offline
          giesbert
          wrote on last edited by
          #18

          Hi Volker,

          one correction regarding signals/slots:

          Afaik, they also work without an event loop, if you only use direct connections. This means in fact a syncronous execution of everything, nothing asynchronous, no user input (only via command line).

          Nokia Certified Qt Specialist.
          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

          1 Reply Last reply
          0
          • mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by
            #19

            It would be helpful if you could describe what you want to do by embedding the existing code into a Qt application environment.

            I thought it might be a good first step, to help me understand the control flow of a Qt application, and where application code is supposed to "live," without actually getting into the nuts and bolts of the GUI yet. The long term plan is definitely to have an event loop.

            1 Reply Last reply
            0
            • Z Offline
              Z Offline
              ZapB
              wrote on last edited by
              #20

              [quote author="mzimmers" date="1301086103"]OK, I'm back. (Had to chase down some bugs for a couple of days.)
              [/quote]

              I'm back too now. Been offline whilst decorating...

              [quote author="mzimmers" date="1301086103"]
              So, regarding this "event loop" -- it seems to be a member function of QWidget, right? I'm curious...what throttles it? I assume it doesn't just run open loop.
              [/quote]

              exec() is a function of QCoreApplication (plus a few other classes QEventLoop, QDialog etc). The purpose of the event loop is to notice "events" (keypresses, mouse moves, window system damage events, network socket or file descriptor events) and translate these into events that can be handled within your Qt application. You normally do this by either overriding a virtual function such as QWidget::resizeEvent( QResizeEvent* e ) or by connecting to a convenient signal from a Qt class such as QIODevice::readyRead(). It depends upon what you are trying to do.

              [quote author="mzimmers" date="1301086103"]
              Also...what happens to my main()? In my main, besides initializing some variables, I have a loop that calls a function. Does this functionality become a function that is passed to the event loop by a connect()?
              [/quote]

              Not normally. There are a few approaches you can take. If the work can easily be split into small packages then you can simply use a timer to do a little bit of work at a time. A similar approach is to not use a timer bu tinstead call QCoreApplication::processEvents() every so often in your loop. Both of these approaches allow control to return to the event loop so that your GUI does not appear to freeze. Remember, whilst the main thread is busy doing your calculations it is not available to paint the screen or handle any other types of events.

              If you work is not easily broken up, or if you want to take advantage of multiple cores or processors then you should take a look at QThread or QtConcurrent. These allow you to move your heavy work to a separate thread (or threads) of execution, leaving the main thread free to update the GUI and handle other events in the event loop. Come back with more questions if you need help with this.

              [quote author="mzimmers" date="1301086103"]
              Let's say I just want to imbed my current program into a Qt application. For right now, I don't even need to create a GUI; I just want to get my program logic contained within the Qt constructs. Do I create a loop function, and use a connect() call to access it?
              [/quote]

              Take a look at the above options and this "Qt Quarterly article":http://doc.qt.nokia.com/qq/qq27-responsive-guis.html.

              [quote author="mzimmers" date="1301086103"]
              And...what's the best source of online documentation for this? The help stuff in Creator seems to have some dead links.
              [/quote]

              The "online documentation":http://doc.qt.nokia.com/latest/.

              Good luck!

              Nokia Certified Qt Specialist
              Interested in hearing about Qt related work

              1 Reply Last reply
              0
              • mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #21

                exec() is a function of QCoreApplication (plus a few other classes QEventLoop, QDialog etc). The purpose of the event loop is to notice “events” (keypresses, mouse moves, window system damage events, network socket or file descriptor events) and translate these into events that can be handled within your Qt application. You normally do this by either overriding a virtual function such as QWidget::resizeEvent( QResizeEvent* e ) or by connecting to a convenient signal from a Qt class such as QIODevice::readyRead(). It depends upon what you are trying to do.

                OK, my main program is pretty simple. It initializes a few variables, and then goes into a loop. The loop will probably be infinite in production mode, but each instance should complete in well under a second.

                Let's say that I'd like to build a GUI for this that displays two values after each loop iteration. I'd probably put a minor delay in, just to prevent the GUI from updating so rapidly that it's hard to read. So...how do I go about this? Each variable needs its own widget, right? With most of the stuff that you have in widget.cpp above?

                Thanks.

                EDIT:

                Also...I've been looking through the online docs, and don't find an entry for emit. I also don't find an entry for dataChanged() which looks right for how you're using it. I DID find an entry for emitDataChanged(). Is the code you used pre 4.7?

                1 Reply Last reply
                0
                • Z Offline
                  Z Offline
                  ZapB
                  wrote on last edited by
                  #22

                  [quote author="mzimmers" date="1301337361"]
                  OK, my main program is pretty simple. It initializes a few variables, and then goes into a loop. The loop will probably be infinite in production mode, but each instance should complete in well under a second.

                  Let's say that I'd like to build a GUI for this that displays two values after each loop iteration. I'd probably put a minor delay in, just to prevent the GUI from updating so rapidly that it's hard to read. So...how do I go about this? Each variable needs its own widget, right? With most of the stuff that you have in widget.cpp above?
                  [/quote]

                  As a first pass, I would try simply putting your existing code into the Generator class that we made earlier. In the calculateNextValue() function would be a good place. Refactor it so that this function only contains the body of your loop. We alreayd have this function being called in response to a timer.

                  You can build up in complexity from there using one of the techniques that I described earlier. From what you have described, putting your infinite loop into a worker thread could well be the best approach. Then you can just emit your calculated values in a signal after a certain amount of time has elapsed (you can use QTime::start() and QTime::elapsed() to measure this).

                  The way in which you display the results of your calculations is entirely up to you. If you just have a pair of doubles, then using a couple of QLabels would be a reasonable approach. If you had 1000 doubles then I would look at using something else, a QTableView for e.g.

                  If you would like some more help in getting any of this to work then feel free to come back with more questions and we'll do what we can to help you. It doesn't sound like it will be particularly complicated.

                  [quote author="mzimmers" date="1301337361"]
                  EDIT:

                  Also...I've been looking through the online docs, and don't find an entry for emit. I also don't find an entry for dataChanged() which looks right for how you're using it. I DID find an entry for emitDataChanged(). Is the code you used pre 4.7?[/quote]

                  The "emit" keyword is just a macro that expands to nothing. It is just semantic sugar to make you think that a signal really is broadcast. In reality, the moc implements the body of the signal function for you.

                  As for our signal, dataChanged(), this is just a signal that we invented for our custom Widget class so you will not find anything about it in the Qt docs.

                  Nokia Certified Qt Specialist
                  Interested in hearing about Qt related work

                  1 Reply Last reply
                  0
                  • mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #23

                    OK, I'm going to start on this in a bit. My goal is to get something working today.

                    Newbie question: what does refactoring do?

                    1 Reply Last reply
                    0
                    • Z Offline
                      Z Offline
                      ZapB
                      wrote on last edited by
                      #24

                      Refactoring just means modifying your existing code so that it works in a different context or is organised differently. In this case moving your loop code and adjusting it as described above.

                      Nokia Certified Qt Specialist
                      Interested in hearing about Qt related work

                      1 Reply Last reply
                      0
                      • mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by
                        #25

                        OK, thanks. So, if I:

                        bring generator and widget files into my existing project

                        take all my stuff out of my main and put it into generator

                        replace my main with the one you posted

                        do the refactor thingie

                        Is that on the right track?

                        1 Reply Last reply
                        0
                        • mzimmersM Offline
                          mzimmersM Offline
                          mzimmers
                          wrote on last edited by
                          #26

                          OK, I've changed my approach slightly. I decided to create a class to contain all the stuff for my main routine. I've called this class Soc, and its only data members are an object of another class (Filter), and some control variables.

                          Now I'm having some trouble getting the Soc constructor right. The Soc constructor needs to pass an argument to the Filter constructor. The problem is, Soc (like generator) inherits its constructor from the QObject class. As such, it isn't prepared to take any additional parameters (like the argument I want to pass).

                          How can I form the Soc constructor so that I can pass an argument to the Filter constructor? Or, is there a better way of doing this?

                          Thanks.

                          EDIT:

                          I think I resolved this problem by adding the Filter initialization to the Soc parameter initialization (did I word that correctly?):

                          @#include "Soc.h"
                          const int resetValue = 55;

                          using namespace std;

                          Soc::Soc(QObject *parent) :
                          QObject(parent), filter(resetValue)
                          {
                          }
                          @

                          Now, I'm getting a symbol not found error:

                          bq. Undefined symbols:
                          "Soc::getCoeffs(int*, int*)", referenced from:
                          Soc::runOneCycle() in Soc.o
                          Soc::qt_metacall(QMetaObject::Call, int, void**)in moc_Soc.o
                          ld: symbol(s) not found
                          collect2: ld returned 1 exit status

                          Is this somehow related to the fact that the calling routine (I've named it Soc::runOneCycle()) is defined as a public slot, and not an "ordinary" member function?

                          EDIT 2:

                          Aargh. Please ignore previous lame question. My fault for trying to work too fast. I'll come back when I have something legit.

                          1 Reply Last reply
                          0
                          • mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on last edited by
                            #27

                            OK...I've cleared the decks of my dumb mistakes (I think). I believe that I have now correctly implemented a class Soc, which contains a routine called runOneCycle() that replaces most of the functionality in my original main(). I now need to "hook it up" so it gets called. I guess the next step is to implement a version of the widget software that Zap posted above. Right now, I'd be happy if it ran 100 times, and showed the results of two variables after each running. (I have lots of plans for enhancing this, but this will do for now.)

                            I won't need a timer (yet), so we can eliminate that part of the code. So...do I need just one connect statement? Or, do I need two, since I'm planning on displaying the values of two variables with the Soc class?

                            Thanks...I think I'm slowly getting closer...

                            1 Reply Last reply
                            0
                            • Z Offline
                              Z Offline
                              ZapB
                              wrote on last edited by
                              #28

                              Are you able to post your code? If yes then please do, if not then we'll have to work with examples still. Not a problem either way...

                              Nokia Certified Qt Specialist
                              Interested in hearing about Qt related work

                              1 Reply Last reply
                              0
                              • mzimmersM Offline
                                mzimmersM Offline
                                mzimmers
                                wrote on last edited by
                                #29

                                I can post some extracts, which would hopefully be good enough. I removed some irrelevant stuff for brevity.

                                Here's Soc.h:

                                @#ifndef SOC_H
                                #define SOC_H

                                #include <QObject>
                                #include <iostream>
                                #include <fstream>
                                #include <iomanip>
                                #include "DemodShaperFilter.h"

                                class Soc : public QObject
                                {
                                Q_OBJECT
                                private:
                                Filter filter; // Soc contains one filter for now.
                                /*

                                • clocks and resets.
                                  /
                                  bool clockEnable;
                                  bool clockState;
                                  // bool systemReset;
                                  bool filterReset;
                                  /
                                • arguments to drive the filter processing.
                                  */

                                int shaperCoeffI[NBR_CELLS];
                                int shaperCoeffQ[NBR_CELLS];
                                int combGainI;
                                int combGainQ;
                                int shaperOutI, shaperOutQ;

                                public:
                                explicit Soc(QObject *parent = 0);
                                int getCoeffs(int *aI, int *aQ);

                                signals:
                                void dataChanged (double value);
                                public slots:
                                void runOneCycle();
                                };
                                #endif // SOC_H
                                @

                                And here's the .cpp file:

                                @#include "Soc.h"
                                const int resetValue = 55;

                                //Soc::Soc(QObject *parent) :
                                // QObject(parent)
                                Soc::Soc(QObject *parent) :
                                QObject(parent), filter(resetValue)
                                {
                                }

                                void Soc::runOneCycle()
                                {
                                static int i=0;
                                int rc;
                                /*

                                • test a single filter.
                                  */

                                // temporarily use simple variables for comb stuff.

                                combGainI = i;
                                combGainQ = i*2;
                                i++;

                                systemClock.setClock(HIGH);
                                filter.cycle(combGainI, // run the high cycle.
                                shaperCoeffI,
                                combGainQ,
                                shaperCoeffQ,
                                shaperOutI,
                                shaperOutQ,
                                clockEnable,
                                filterReset);

                                return;
                                }
                                @

                                1 Reply Last reply
                                0
                                • mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #30

                                  So...I've added the widget files from the example above to my program, and changed m_generator to a Soc variable called (creatively enough) soc. The program runs, and produces the correct output (as displayed on the console), but I'm not getting anything in my GUI window.

                                  I believe I need to modify this line of code in widget.cpp:

                                  @ connect (soc, SIGNAL(dataChanged(double)), this, SLOT(setValue(double)));
                                  @

                                  I imagine I'd have to modify the doubles to ints, but...I need to tell it to look at my two variables. Do I:

                                  1. need two connect statements for this?
                                  2. replace "this" with soc.member-name?

                                  I guess I should also modify setValue to accept an int instead of a double, too.

                                  Thanks.

                                  1 Reply Last reply
                                  0
                                  • G Offline
                                    G Offline
                                    giesbert
                                    wrote on last edited by
                                    #31

                                    Thje connect is correct. But I fI look at your last code, where do you emit the signal?

                                    Nokia Certified Qt Specialist.
                                    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                    1 Reply Last reply
                                    0
                                    • mzimmersM Offline
                                      mzimmersM Offline
                                      mzimmers
                                      wrote on last edited by
                                      #32

                                      Oops.

                                      I guess I need a emit dataChanged() call, don't I?

                                      So, my question now is...what do I put in as a parameter for this call? I guess this is the missing link to my understanding of how these signals work. (It also looks like I missed changing a double to int in the Soc.h file.)

                                      Thanks.

                                      1 Reply Last reply
                                      0
                                      • G Offline
                                        G Offline
                                        giesbert
                                        wrote on last edited by
                                        #33

                                        Hi,

                                        you have to put a double in, as specified in the header.
                                        Which one, I can't tell you, that's depending on your application.
                                        Typically, the value you want to notify :-)

                                        Nokia Certified Qt Specialist.
                                        Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                        1 Reply Last reply
                                        0
                                        • mzimmersM Offline
                                          mzimmersM Offline
                                          mzimmers
                                          wrote on last edited by
                                          #34

                                          So, I use a double in the call even if the variable I want to display is an int? What exactly does that double represent: I thought it was the variable I wanted to display...

                                          EDIT: I just put the dataChanged() call into my code, and it seems to work. Now, if I want to do this for two variables, what all do I have to duplicate? Obviously, I'll need two calls to dataChanged(), but what else do I have to do?

                                          Thanks.

                                          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