【问题标题】:Passing Data From Qt To Primitive Types In C++将数据从 Qt 传递到 C++ 中的原始类型
【发布时间】:2014-02-07 02:49:14
【问题描述】:

我在一个用 Qt 编写的 GUI 上有一个按钮。此按钮的作用是将整数值增加 2。然后,该新值将显示在同一 GUI 上的小部件中。我的目标是将这个递增的值传递给原始数据类型,在本例中为 int。

增量按钮允许您增加显示在 GUI 上的值,这意味着我在这两个 GUI 元素之间使用了 SIGNAL 和 SLOT 协议。

SIGNAL 和 SLOT 与动作侦听器协议不同,因此,我似乎无法更新我在每次单击鼠标按钮时存储此值的 int。每次用户单击 GUI 上的增量按钮时,我都需要能够更新这个 int 值……最终目标是将此值传递给另一个用 C++ 编写的数学函数。下面是我试图弄清楚如何做到这一点的尝试。注意,在 GUI 运行的整个过程中,只打印出一个值,即存储在 outVal 中的初始值。如果这使用了动作侦听器,那么这将不是问题。所以我的问题是,每次点击鼠标时如何更新outVal...谢谢!

#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;
}

编辑:在我得到建议后,我尝试了这个

#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;
}

这是我的错误

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/usr/include/qt5 -I/usr/include/qt5/QtWidgets -I/usr/include/qt5/QtGui -I/usr/include/qt5/QtCore -I. -o 示例1.o 示例1.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:在函数Counter::setValue(int)': example1.cpp:(.text+0x9): undefined reference toCounter::valueChanged(int)' example1.o:在函数main': example1.cpp:(.text.startup+0x25): undefined reference tovtable 中用于计数器' example1.cpp:(.text.startup+0x94): undefined reference to `Counter::valueChanged(int)' collect2:错误:ld 返回 1 个退出状态 make: * [gui1] 错误 1

仅供参考;我运行“qmake -project”,然后运行“qmake”,然后运行“make”。

编辑:最终的工作版本!故事的寓意是,使用头文件、函数定义和驱动程序在单独的 c++ 文件中将所有内容放在适当的位置,这使得使用 QT 时的生活变得更加轻松。这里的具体问题是 MOC 没有运行,因为驱动程序(主)和 QObject 类在同一个文件中。

//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;
}

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    增量按钮允许您增加显示在 GUI 上的值,这意味着 ive (sic) 在这两个 GUI 元素之间使用了 SIGNAL 和 SLOT 协议

    这就是问题所在。您应该做的是将任何数据模型与其可视化表示分开。如果将数据存储在一个类中,我们称之为Model,然后将按钮连接到Model类中的一个槽,槽函数可以更新它的值,然后发出一个信号来更新数据的视图。

    例如:

    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);
    }
    

    有一个很好的设计模式扩展了这个叫做 MVC (Model View Controller)

    【讨论】:

    • 非常好!所以我认为实现插槽由我决定,信号呢?我们已经定义了 UpdateView(int value),但它实际上是怎么做的呢?
    • 您不必实现 SIGNAL - 您只需声明它。其余的由“Qt-magic”完成,cp。 qt-project.org/doc/qt-4.8/signalsandslots.html 分别。 Qt moc 编译器,cp。 qt-project.org/doc/qt-4.8/moc.html#moc
    • 我将深入研究 MVC。但到目前为止,我无法编译这个简单的例子。我花了一整天的时间浏览 C++ 的东西(我真的不知道这门语言,我更像是一个 C 和 Java 人)。这是我的代码
    • 如果如您的代码所示,Counter 类位于 main.cpp 中,我认为您需要手动#include 该类的 moc 文件。或者,将 Counter 类移动到分离头文件和实现文件,清理构建,调用 qmake 重建 moc 文件,然后编译项目。
    • @Merlin069 我还尝试使用头文件、定义函数和类的文件以及主文件将所有内容放在适当的位置,代码行“emit valueChanged(value )”。并且自动生成的 moc 文件说不要将它包含在任何东西中
    猜你喜欢
    • 2012-11-25
    • 2012-06-25
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    相关资源
    最近更新 更多