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] Read checkbox checked state?
QtWS25 Last Chance

[SOLVED] Read checkbox checked state?

Scheduled Pinned Locked Moved General and Desktop
23 Posts 3 Posters 13.8k 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.
  • J Offline
    J Offline
    jediengineer
    wrote on last edited by
    #1

    Hi all, I'm a little shaky with the QML, and a bit of a newbie to anything but embedded C for microcontrollers, so bear with me.. I'm trying to read the state of a number of checkboxes. Basically, when a box is checked, I'd like for a subroutine that is called from a button click, to read the neighboring checkbox, and perform it's task based on the state of the check box.

    I've seen several examples in other threads on this forum, but I'm not sure I understand it. Also, a lot of posts make reference to linked pages which no longer exist, or lead to somewhere new. At this point, I've constructed the object, but I'm not sure what to do with it from here to read if the box is checked, and not sure how to specify which checkbox to read. So far:

    @ QQuickView view;
    view.setSource(QUrl::fromLocalFile("main.qml"));
    view.show();
    QObject *cbox = view.rootObject();@

    This was from an example of something slightly different, and the suggestion was to use QQuickView. in my qml file, I have 5 or so checkboxes set up as such:

    @ CheckBox {
    id: left
    x: 86
    y: 3
    text: "Left"
    }

            CheckBox {
                id: right
                x: 172
                y: 3
                text: "Right"
            }@
    

    How would I individually read the state of each checkbox from this point?

    Another method I explored (but it wouldn't compile) was this (using the same qml code):

    @QSettings settings;

    QCheckBox* left->Left;                                     
    QCheckBox* right->Right;
    
    Left->setChecked(settings.value("checkstate").toBool());
    Right->setChecked(settings.value("checkstate").toBool());@
    

    And as far as I can tell, this should save the state of the checkbox to a boo called left (and right). It doesn't compile, and I'm a little lost. If someone could show me the error of my ways, slightly dumbed down, that would be appreciated. Thanks!

    1 Reply Last reply
    0
    • T Offline
      T Offline
      t3685
      wrote on last edited by
      #2

      First of all you are using C/C++ code in QML (which is a different language) so that won't work :).

      QML works with properties. If you want to react to a change of the checked property you do the following:

      @
      CheckBox {
      id: left
      x: 86
      y: 3
      text: "Left"
      onCheckedChanged: /your code/
      }@

      You can find more documentation here:

      http://qt-project.org/doc/qt-5.1/qtdoc/qmlfirststeps.html

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jediengineer
        wrote on last edited by
        #3

        Thanks t3685, but all that code was in my C/C++ file, except for the button code which I specified was in my qml file. I guess I'll have to edit and label it to avoid further confusion. I've read the link you posted, but that didn't help answer my question. I want to know how to read the state of a checkbox (is it checked or not) from my C/C++ code. I'm told for the last 1000 pages I've read that it can be done, but every example shown was of how to change the state of a checkbox, not read it.

        In your example, you added "onCheckedChanged:" - this would mean that I have to connect the signal to a slot that would define an action to be called when the checkbox is changed. I'm just looking to read its state from the C/C++ side.

        1 Reply Last reply
        0
        • T Offline
          T Offline
          t3685
          wrote on last edited by
          #4

          ah I misunderstood your question

          http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#property
          http://qt-project.org/doc/qt-5.0/qtqml/qtqml-cppintegration-interactqmlfromcpp.html

          I hope these links helped. I should add though that it's better design you have your gui invoke c++ methods than to read the state from the ui from c++. that way if you ever modify your ui you don't need to change your c++ code. of course you may have your reasons :-)

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jediengineer
            wrote on last edited by
            #5

            Well, up until this morning, there was only supposed to be one gui program, now I'm being told I'm needed to make a few more... I can't win. But those links helped, thanks!! So I guess I'll be doing it your way after all. I have a few buttons that are set up that way as well, as shown below:

            QML:

            @Rectangle {
            id: main
            width: 800
            height: 600
            color: "#abcfe9"
            border.width: 4
            border.color: "#000000"

            signal buttonClicked_enable()
            
                    Button {
                    id: enable
                    x: 0
                    y: 25
                    text: "Enable"
                    onClicked:buttonClicked_enable()
                }
            

            }@

            And on the C++ side I have:

            @class TLA_Funcs : public QObject
            {
            Q_OBJECT
            public slots:
            void sys_enable(void);
            ....
            protected
            ....
            }

            int main (int argc, char*argv[]) {

            QGuiApplication app(argc, argv);
            
            QQuickView *view = new QQuickView(QUrl("main.qml"));                   
            view->show();                                                           
            QQuickItem *button = view->rootObject();                               
            TLA_Funcs *funcs = new TLA_Funcs();                                     
            
            // connect signals to slots:
            QObject::connect(button, SIGNAL(buttonClicked_enable()), funcs, SLOT(sys_enable()));
            

            ....
            }@

            but when I compile, I get an error message that only says "required from here" for the code that connects my signal to my "sys_enable()" slot. The function is not fully defined, but it does have a cout<< statement in it to give it something to do... What would cause that error? I could use a little insight on that before I start creating signals and slots for my checkboxes...

            1 Reply Last reply
            0
            • T Offline
              T Offline
              t3685
              wrote on last edited by
              #6

              You'll probably want to read this then:

              http://qt-project.org/doc/qt-5.0/qtqml/qtqml-cppintegration-topic.html

              As for your problem,

              @onClicked@

              is already the slot so you don't need to make any connections anymore.
              So when a user clicks on the button the signal "clicked" is emitted, the "on<Signal>" syntax allows you to define what should happen when that button is clicked.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jediengineer
                wrote on last edited by
                #7

                I'm not sure I follow what you're saying...

                @signal buttonClicked_enable()@ doesn't need to be there?

                @onClicked@ needs to be in the button code to direct the signal to the proper slot, right? and on the C++ side, you need to connect the signal name to the slot right? I've done it this way because I have many buttons to address...

                1 Reply Last reply
                0
                • JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #8

                  Signals and slots between QML and C++
                  As far as the C++ side can tell, your QQuickItem is a black box. Your C++ code cannot see what's inside your QQuickItem -- it cannot see your buttons or checkboxes.

                  The purpose of adding signal buttonClicked_enable() to your top-level QML item was to create an interface between your QML code and C++ code. C++ cannot see the signals that are emitted by your "inner" buttons/checkboxes, but it can see the signals emitted by your top-level item. So, in order for your QML Button's signal to reach C++ land, you relay it through the top-level signal.

                  A note about clicked() and onClicked(): When you click the Button, it emits the clicked() signal. It is just like any other signal -- you can connect to any slot(s) of your choice (assuming that the signal can reach that slot, of course). onClicked() is a special slot (called a "signal handler") that is built into the Button. It is auto-connected to the clicked() signal, so you don't need to explicitly make the connection yourself.

                  So, in your code...
                  @
                  Rectangle {
                  id: main
                  signal buttonClicked_enable()

                  Button {
                      id: enable
                      onClicked:buttonClicked_enable()
                  }
                  

                  }
                  @
                  ...when you click your Button, this sequence occurs:

                  The Button emits the clicked() signal.

                  This signal calls the Button's onClicked() slot.

                  In your code, the onClicked() slot does one thing only: emit the top-level Rectangle's buttonClicked_enable() signal.

                  (Assuming that you made the C++ connection) The buttonClicked_enable() passes into C++ land, and activates your sys_enable() slot.

                  Passing data from QML into C++
                  There are 2 ways to pass data from QML out into C++:

                  Signals with parameters can be used to pass data to slots that accept these parameters

                  QML makes extensive use of "dynamic properties":http://qt-project.org/doc/qt-5/properties.html#reading-and-writing-properties-with-the-meta-object-system (this article was written for C++. Ignore the long section about Q_PROPERTY, go straight to "Reading and WritingProperties")

                  @
                  // QML
                  Rectangle {
                  id: main
                  signal signalWithParam(bool myParam)
                  property bool myBooleanProperty: false

                  //...
                  

                  }
                  @

                  @
                  // C++
                  QQuickView *view = new QQuickView(QUrl("main.qml"));
                  QQuickItem *qmlItem = view->rootObject();
                  TLA_Funcs *funcs = new TLA_Funcs();

                  // Connect signals to slots
                  QObject::connect(qmlItem, SIGNAL(signalWithParam(bool)), funcs, SLOT(slotThatAcceptsParam(bool)));

                  // Read property
                  bool valueFromQml = qmlItem->property("myBooleanProperty").toBool();
                  @

                  How to use your checkbox to emit the signal or set the property in QML is left as an exercise :)

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    jediengineer
                    wrote on last edited by
                    #9

                    Thanks JKSH, good info - and I pretty much understand that info already. But a refresh was good!! I was trying to understand the other guy's information, because it was a little vague:

                    [quote author="t3685" date="1392293795"]

                    As for your problem,

                    @onClicked@

                    is already the slot so you don't need to make any connections anymore.
                    So when a user clicks on the button the signal "clicked" is emitted, the "on<Signal>" syntax allows you to define what should happen when that button is clicked.
                    [/quote]

                    Connecting the checkboxes to the c++ was practically the same as when you explained the buttons in the other thread, but instead of onClicked() I used onCheckedChenged() and my slot function handles it. Now the only issue I'm working through is in the c++ side, where the line:

                    @QObject::connect(stuff, SIGNAL(buttonClicked_enable()), funcs, SLOT(sys_enable()));@

                    is rejected by the compiler with the following errors:

                    "X:\Lambda UDP Test Program\Lambda_UDP_Test_GUI\TLA_UDP.cpp:122: note: candidate expects 3 arguments, 4 provided QObject::connect(stuff, SIGNAL(buttonClicked_inhibit()), funcs, SLOT(sys_enable()));"

                    and

                    "C:\Qt\Qt5.2.1MinGw\5.2.1\mingw48_32\include\QtCore\qobject.h:-1: In substitution of 'template<class Func1, class Func2> static typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) [with Func1 = const char*; Func2 = const char*]': X:\Lambda UDP Test Program\Lambda_UDP_Test_GUI\TLA_UDP.cpp:122: required from here"

                    I'm still trying to hunt down the reason. I've been on the QObject resurce page looking at QObject::Connect() condition, and even in their examples, they are showing 4 arguments structured the same as what I have. So I'm a little puzzled as to what's holding that back... and I put this in this thread because it pertains to the way I set up the checkboxes.

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      t3685
                      wrote on last edited by
                      #10

                      What I meant was that onClicked is already a slot, and it seems weird to throw another signal from there.

                      1 Reply Last reply
                      0
                      • JKSHJ Offline
                        JKSHJ Offline
                        JKSH
                        Moderators
                        wrote on last edited by
                        #11

                        [quote author="jediengineer" date="1392309698"]
                        @QObject::connect(stuff, SIGNAL(buttonClicked_enable()), funcs, SLOT(sys_enable()));@

                        is rejected by the compiler with the following errors:

                        "X:\Lambda UDP Test Program\Lambda_UDP_Test_GUI\TLA_UDP.cpp:122: note: candidate expects 3 arguments, 4 provided QObject::connect(stuff, SIGNAL(buttonClicked_inhibit()), funcs, SLOT(sys_enable()));"
                        [/quote]Erase the line and re-type it. I suspect a typo.

                        [quote author="t3685" date="1392319949"]What I meant was that onClicked is already a slot, and it seems weird to throw another signal from there.[/quote]Why is it weird?

                        • It's perfectly valid to chain multiple signals together.
                        • This design can be used to enforce modularity/encapsulation.
                        • You can emit a signal with parameters in response to a click.

                        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          t3685
                          wrote on last edited by
                          #12

                          the clicked signal is no more or less encapsulated than the custom signal you defined in your button. it is just as accessible to everyone else. since you are not using it with any parameters or I must have looked over out it felt a little redundant to me :-). any case good luck!

                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            jediengineer
                            wrote on last edited by
                            #13

                            Ok, retyping didn't help. T3685, in my case, I have about 23 buttons I'm assigning to slots. How would you differentiate them all, based on what you said?

                            1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              jediengineer
                              wrote on last edited by
                              #14

                              Ok, here's a screenshot of the error:

                              !http://tinypic.com/r/2vsoups/8()!

                              Sorry, it's the first place I found to host the picture...

                              1 Reply Last reply
                              0
                              • JKSHJ Offline
                                JKSHJ Offline
                                JKSH
                                Moderators
                                wrote on last edited by
                                #15

                                [quote author="jediengineer" date="1392386177"]Ok, here's a screenshot of the error:

                                !http://tinypic.com/r/2vsoups/8()!

                                Sorry, it's the first place I found to host the picture... [/quote]Your compiler doesn't know what a QQuickItem is, and doesn't realize that it can take part in signal-slot connections. To inform your compiler,
                                @#include <QQuickItem>@

                                By the way, the "is required here" message is only an extra note that comes after the actual error message. The real error message (which is the message you'd use to find the root of the problem) is at the 1st red exclamation mark.

                                [quote author="t3685" date="1392361043"]the clicked signal is no more or less encapsulated than the custom signal you defined in your button. it is just as accessible to everyone else. since you are not using it with any parameters or I must have looked over out it felt a little redundant to me :-). any case good luck! [/quote]I meant encapsulating the buttons/checkboxes away from C++ code. :) The OP's slot is a C++ function.

                                Granted, it's not very "hidden" at the moment because the signal name is "buttonClicked_enable()", but that's a different matter.

                                [quote author="jediengineer" date="1392378240"]T3685, in my case, I have about 23 buttons I'm assigning to slots. How would you differentiate them all, based on what you said?[/quote]t3685 meant that you can call your C++ slots directly from QML, without adding the extra "buttonClicked_enable()" signal. It's the "shorter method" that I hinted at in http://qt-project.org/forums/viewthread/37907/

                                If you're eager to investigate it, that method involves inserting your C++ object into QML as a "context property":http://qt-project.org/doc/qt-5/qtqml-cppintegration-contextproperties.html. However, I still recommend that you leave context properties for later, and focus on mastering the signal-slot method first. The latter is much more useful for Qt programming overall.

                                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                1 Reply Last reply
                                0
                                • J Offline
                                  J Offline
                                  jediengineer
                                  wrote on last edited by
                                  #16

                                  Holy Crap, JKSH, I can't believe it was as simple as a header file... I'm not sure how I didn't catch that, maybe it's because QQuickView highlighted itself in green, so I assumed it was recognized... Well, I feel dumb. But thanks for pointing that out...

                                  I won't bother with the context property for now unless this runs at a snail's pace, which I suspect it won't. Thanks again, you've given me an insight to how some of this stuff works, and I appreciate it! Now I've got a little reading to do on checkbox signals... Thanks a million!!

                                  1 Reply Last reply
                                  0
                                  • J Offline
                                    J Offline
                                    jediengineer
                                    wrote on last edited by
                                    #17

                                    Ok, one last question about this - I think I've got a destructor issue... now I'm not too sure of myself with destructors, but I've tried a few different ways to fix this. Everything compiles fine except the class - I get a "undefined reference to 'vtable for TLA_Funcs' " message when I compile. I know this has something to do with the destructor, and I'm trying to figure it out, and I've even tried several recommended methods for fixing it, posted on stackoverflow... but nothing seems to help. Any ideas? Again, here's my class, and it's in my custom header file...

                                    @class TLA_Funcs : public QObject {

                                    Q_OBJECT
                                    

                                    public slots:
                                    void sys_enable(){return;} // enable left, right, or both inverters
                                    void sys_inhibit(){return;} // inhibit left, right, or both inverters
                                    void sys_hard_inhibit(){return;} // inhibit system via main inhibit line
                                    void sys_disable(){return;} // disable entire system
                                    void sys_autoupdate(){return;} // enables or disables autoupdate
                                    void sys_reset(){return;} // resets analog inverter controller
                                    void sys_observe(){return;} // forces observation mode
                                    void sys_dac_test(){return;} // performs DAC self test
                                    void sys_reset_dac(){return;} // resets the DAC
                                    void sys_read_adc(){return;} // reads ADC inputs
                                    void sys_read_mux(){return;} // reads MUX inputs
                                    void sys_poll(){return;} // Quick ADC and MUX poll
                                    void sys_set_voltage(){return;} // sets output voltage percent
                                    void sys_set_current(){return;} // sets output current percent
                                    void sys_set_power(){return;} // sets output power percent
                                    void sys_set_all(){return;} // sets all output controls simultaneously by percent
                                    void sys_save_dac_settings(){return;} // save all dac settings
                                    void sys_delete_dac_settings(){return;} // delete saved dac settings
                                    void sys_restore_dac_settings(){return;} // restores saved settings from memory
                                    void sys_cpu_reset(){return;} // resets CPU
                                    void sys_cpu_halt(){return;} // halts cpu
                                    void sys_self_check(){return;} // performs full system check.
                                    void sys_adc_test(){return;} // ADC test

                                    void sys_left_inv(){left_inv = !left_inv;}
                                    void sys_right_inv(){right_inv = !right_inv;}
                                    void sys_step(){step = !step;}
                                    void sys_fine_step(){fine = !fine;}
                                    void sys_step_up(){up = !up;}
                                    void sys_spec_mux(){specific_mux = !specific_mux;}
                                    void sys_spec_adc(){specific_adc = !specific_adc;}
                                    

                                    protected:
                                    bool left_inv;
                                    bool right_inv;
                                    bool step;
                                    bool fine;
                                    bool up;
                                    bool specific_mux;
                                    bool specific_adc;
                                    };@

                                    I've tried a bunch of different methods of constructing and destructing, but nothing seems to work. Any ideas?

                                    1 Reply Last reply
                                    0
                                    • JKSHJ Offline
                                      JKSHJ Offline
                                      JKSH
                                      Moderators
                                      wrote on last edited by
                                      #18

                                      [quote]I get a “undefined reference to ‘vtable for TLA_Funcs’ “[/quote]No destructors involved here.

                                      This error can be cause by a few different things. In your case, you just have an outdated Makefile. You need to generate a new one if you add "Q_OBJECT" to any class:

                                      Build -> Clean Project _____ (not strictly necessary, but I do it just in case)

                                      Build -> Run qmake

                                      Build -> Build Project _____

                                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                      1 Reply Last reply
                                      0
                                      • J Offline
                                        J Offline
                                        jediengineer
                                        wrote on last edited by
                                        #19

                                        err... Nope, that wasn't it. Same error as before. Still pointing to my class with the "undefined reference to 'vtable for TLA' " error message.

                                        I'm fiddling with it, trying to understand this. This is quite a change from what I'm used to doing with embedded DSP processors...

                                        1 Reply Last reply
                                        0
                                        • JKSHJ Offline
                                          JKSHJ Offline
                                          JKSH
                                          Moderators
                                          wrote on last edited by
                                          #20

                                          [quote author="jediengineer" date="1392503915"]err... Nope, that wasn't it. Same error as before. Still pointing to my class with the "undefined reference to 'vtable for TLA' " error message.

                                          I'm fiddling with it, trying to understand this. This is quite a change from what I'm used to doing with embedded DSP processors...[/quote]Another cause of this error is if you declared TLA_Funcs in a .cpp file.

                                          Qt uses a "code generator":http://qt-project.org/doc/qt-5/why-moc.html to support signals+slots and many other features. The code generator (called 'moc', for "Meta-Object Compiler") requires all QObject declarations to be put in an header files.

                                          Solution: Move your TLA_Funcs declaration to a .h file (Remember to run qmake afterwards)

                                          P.S. Add a constructor to your class to initialize all its variables to a default value. If you don't do this, they will contain random garbage values.
                                          @
                                          public:
                                          TLA_Funcs(QObject *parent = 0) : QObject(parent)
                                          {
                                          // Initialize all your member variables here
                                          }
                                          @
                                          P.P.S. Use "private", not "protected". "Protected" is for subclassing.

                                          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                          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