简体   繁体   中英

Passing Data From Qt To Primitive Types In C++

I have a button on a GUI written in Qt. What this button does is increasing an integer value by 2. This new value is then displayed in a widget on that same GUI. My goal is to pass this incremented value to a primitive data type, in this case and int.

The increment button allows you to increment a value which is displayed on the GUI, this means that I've used a SIGNAL and SLOT protocol between these two GUI elements.

SIGNAL and SLOT is different from action listener protocol and so, I can't seem to update the int I'm storing this value in per mouse button click. I need to be able to update this int value every time the user clicks the increment button on the GUI....the final goal is to pass this value to another mathematical function written elsewhere in C++. Below is my attempt at trying to figure out how to do just that. Note, the whole time the GUI runs, there is only one value printed out, that is the initial value stored in outVal . If this used action listeners then this would be a non-issue. So my question is, how do I update outVal every time there is a mouse click...thanks!

#include <QApplication>
#include <QGridLayout>
#include <QLabel>
#include <QSpinBox>

#include <string>
#include <stdlib.h>
#include <stdio.h>


#define MIN_WIDTH 350
#define MIN_HEIGHT 300

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

    int outVal = 99;

    QApplication a(argc, argv);

    QWidget window;

    window.setMinimumSize(MIN_WIDTH,MIN_HEIGHT);


    QVBoxLayout * mainPlatter = new QVBoxLayout(&window);
    QSpinBox * spinBox = new QSpinBox;


    spinBox->setRange(1,77);
    spinBox->setSingleStep(2);






    QLabel * label = new QLabel("1");





    mainPlatter->addWidget(spinBox);;
    mainPlatter->addWidget(label);
    QObject :: connect( spinBox, SIGNAL(valueChanged(int)) , label, SLOT(setNum(int)));



    outVal = spinBox->value();
    window.show();


    printf("%d\n",outVal);

    return a.exec();



    return 0;
}

Edit: After the advice i got, this is what i tried

#include <iostream>
#include <QObject>
using namespace std;

class Counter : public QObject{
    Q_OBJECT
     signals:
            void valueChanged(int newValue);
    public:
            Counter(){
                    m_value = 1;
            }
            int value() const {
                    return m_value;
            }
    public slots:
            void setValue(int value);
    private:
            int m_value;

 };
void Counter::setValue(int value){ 
    if(value != m_value){ 
            m_value = value;
            emit valueChanged(value);
    }

}
int main(void){
    Counter a, b;
    QObject :: connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));

    a.setValue(7);

    cout << "a.setValue(7) " << endl;
    cout << "(a.value, b.value) = " << a.value() << b.value() << endl;



    return 0;
}

these are my errors

g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/share/qt5/mkspecs/linux-g++-64 -I. -I. -I/usr/include/qt5 -I/usr/include/qt5/QtWidgets -I/usr/include/qt5/QtGui -I/usr/include/qt5/QtCore -I. -o example1.o example1.cpp g++ -m64 -Wl,-O1 -o gui1 example1.o -L/usr/X11R6/lib64 -lQt5Widgets -L/usr/lib/x86_64-linux-gnu -lQt5Gui -lQt5Core -lGL -lpthread example1.o: In function Counter::setValue(int)': example1.cpp:(.text+0x9): undefined reference to Counter::valueChanged(int)' example1.o: In function main': example1.cpp:(.text.startup+0x25): undefined reference to vtable for Counter' example1.cpp:(.text.startup+0x94): undefined reference to `Counter::valueChanged(int)' collect2: error: ld returned 1 exit status make: * [gui1] Error 1

an FYI; I ran "qmake -project" then "qmake" then "make".

EDIT: The final working version! Moral of the story, put everything in its proper place using headers files, function definitions and drivers in separate c++ files, it makes life a lot easier when using QT. The specific issue here was the the MOC was not running since the driver(main) and the QObject class were in the same file.

//function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <QObject>

class Counter : public QObject {
    Q_OBJECT

    public:
            Counter(){
                    m_value = 1;
            }
            int value() const {
                    return m_value;
            }
    public slots:
            void setValue(int value);
    signals:
            void valueChanged(int newValue);
    private:
            int m_value;

};

#endif

//function.cpp
#include "function.h"
void Counter :: setValue(int value){ 
    if(value != m_value){ 
            m_value = value;
            emit valueChanged(value);
    }

}

//main.cpp
#include <iostream>
#include <QObject>

#include "function.h"
using namespace std;

int main(void){
 Counter a, b;
    QObject :: connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));

    a.setValue(7);

    cout << "a.setValue(7) " << endl;
    cout << "(a.value, b.value) = " << a.value() << b.value() << endl;


    return 0;
}

The increment button allows you to increment a value which is displayed on the GUI, this means that ive (sic) used a SIGNAL and SLOT protocol between these two GUI elements

This is where the problem lies. What you should do is separate any data model from its visual representation. If you store the data in a class, let's call it Model, then connect the button to a slot in the Model class, the slot function can update its value and then emit a signal to update the view of the data.

For example:

class Model : public QObject
{
    Q_OBJECT

    signals:
        // connect this signal to the spin box setValue slot
        void UpdateView(int value);

    public slots:
        // connect this slot to the push button released() signal
        void IncrementValue();

    private:
        int m_value;
}

void Model::IncrementValue()
{
    m_value += 2;
    emit UpdateView(m_value);
}

There is a great design pattern that extends this called MVC ( Model View Controller )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM