2016-06-27 5 views
0

이 책에서 예제이 QT 코드의 GUI의 모든 요소에 값을 전달하지 : 책으로우리가 어떻게 여기 QT4에 책을 읽고 있어요

QApplication a(argc, argv); 
QWidget window; 

QVBoxLayout* mainLayout = new QVBoxLayout(&window); 

QLabel* label = new QLabel("0"); 
QSpinBox* spinBox = new QSpinBox; 
QSlider* slider = new QSlider(Qt::Horizontal); 

mainLayout->addWidget(label); 
mainLayout->addWidget(spinBox); 
mainLayout->addWidget(slider); 

QObject::connect(spinBox, SIGNAL(valueChanged(int)), label, SLOT(setNum(int))); 
QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); 
QObject::connect(slider, SIGNAL(valueChanged(int)), label, SLOT(setNum(int))); 
QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); 

window.show(); 

및 위젯 중 하나의 값을 변경하면 다른 요소의 값이 변경됩니다.

무엇을 모르겠다.은 어떻게 되는가? 한 위젯에서 그 값을 나머지로 전달하는 방법은 무엇입니까? 하나의 위젯을 통해 변경되고 다른 위젯으로 전달되는 변수는 없습니다.

추신 : 개념적으로, 나는 슬롯과 신호 및 '연결'에 대한 아이디어를 이해합니다. 한 위젯에서 다른 위젯으로 값이 전달되는 방식이 문제입니다.

답변

1

신호는 moc (메타 오브젝트 컴파일러)이라는 유틸리티에서 생성 된 코드가있는 C++ 메소드입니다. 슬롯은 일반적인 C++ 방법이며 코드는 사용자가 제어 할 수 있습니다. 연결은 어떤 슬롯을 호출할지 신호에 알리는 방법입니다. 신호가 방출되면 실제로는 연결 목록을 반복하는 시스템 생성 메소드를 호출한다는 의미입니다.

개념적으로는 valueChanged 신호 구현은 다음과 같다 : 상기 슬라이더는 "방출"때

void valueChanged(int value) { 
    for (slot : this->slots) 
    (slot.object->*slot.method)(value); 
} 

따라서, 그 신호는 그 소정의 값으로 각각의 슬롯을 요구한다. 연결이 이루어진 후에는 일을 같이 spinbox의 valueChanged 신호 생각해야 다음

신호 슬롯 메커니즘이기 때문에 핵심에서 변경됩니다 더 "변수가"없다
void SpinBox::valueChanged(int value) { 
    // 1st connection 
    label->setNum(value); 
    // 2nd connection 
    slider->setVale(value); 
} 

쉬운 - 투 메소드 포인터와 인스턴스 포인터를 통해 간접 메소드 호출을 수행하는 방법을 사용합니다. 현대적인 코드에서

이 (Qt5는/C++ 11), 그 예는 것 (이것이 전체 코드) :

#include <QtWidgets> 

int main(int argc, char** argv) { 
    QApplication a{argc, argv}; 
    QWidget window; 

    QVBoxLayout mainLayout{&window}; 

    QLabel label{"0"}; 
    QSpinBox spinBox; 
    QSlider slider{Qt::Horizontal}; 

    mainLayout.addWidget(&label); 
    mainLayout.addWidget(&spinBox); 
    mainLayout.addWidget(&slider); 

    QObject::connect(&spinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), 
        &label, static_cast<void(QLabel::*)(int)>(&QLabel::setNum)); 
    QObject::connect(&spinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), 
        &slider, static_cast<void(QSlider::*)(int)>(&QSlider::setValue)); 
    QObject::connect(&slider, static_cast<void(QSlider::*)(int)>(&QSlider::valueChanged), 
        &label, static_cast<void(QLabel::*)(int)>(&QLabel::setNum)); 
    QObject::connect(&slider, &QSlider::valueChanged, &spinBox, &QSpinBox::setValue); 

    window.show(); 
    return a.exec(); 
} 
관련 문제