2017-05-20 15 views
1

Qt 환경을 처음 접했습니다. 저는 최근에 간단한 채팅 응용 프로그램 (QMainWindow)에 대한 QtCreator 프로젝트를 시작했습니다. 나는 거의 프로젝트를 완료했지만 SIGNAL/SLOT problem을 고수했다.Qt5에서 SLOT 값을 반환하려면 어떻게해야합니까?

나를 간략하게 내 문제를 설명하자

을 인하여 내가 여기에 붙여 넣기 할 수없는 나는 코드의 길이.

  1. 나는 두 클래스 MainWindowNetworkFile 있습니다.
  2. NetworkFile에있는 newServerConn() 함수는 readyRead() 신호를 readFromClient() 슬롯에 연결합니다.
  3. 클라이언트가 반환 한 문자열은 QStringreadFromClient() 슬롯에 저장됩니다.

문제 : 난 단지 그때는 plainLineEdit에 문자열을 인쇄 할 수있을 것입니다 때문에 newServerConn() 기능과 거기에서 MainWindow 클래스의 함수에 슬롯에 QString를 반환해야

ui 오브젝트가 가리키는 위젯.

질문 1 : 어떻게 슬롯에서 값을 반환 할 수 있습니까?

질문 2 : 또는 내가 거기에서 위젯을 사용할 수 있도록 내가 NetworkFile 클래스의 ui 인스턴스의 사본을 얻을 수있는 방법이?

감사합니다. documentation 에서뿐만

+0

"때문에 코드의 길이에 내가 할 수 없습니다입니다 여기에 붙여 넣으세요. "어쨌든 * 여기에 * 이러한 코드를 붙여 넣어야합니다. 질문을 묻는 사람으로서의 당신의 직업은 문제를 재현하는 최소한의 예를 제공하는 것입니다. 자동으로 발생하지는 않습니다. 저장소에있는 지사가 문제를 최소화하고 단일 파일로 최소화하면 오직 질문의 일부로 게시하십시오. 질문에 포함하기에 합당하다고 여겨지는 150 줄 아래에서 재현되지 않는 문제는 거의 없습니다. –

답변

1

나는 신호로 데이터를 방출하고 새로운 신호와 슬롯을 추가 한 슬롯 사이의 연결을 연결합니다.

빠른 자체 포함 예제 (어떤 코드 길이로 인해 여기에 붙여 넣을 수 없습니다."단지 변명, 당신은 거의 항상

헤더) 귀하의 관련 코드를 줄일 수있다 :

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 
#include <QTcpServer> 
#include <QTcpSocket> 
#include <QTextEdit> 

class NetworkFile; 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(){} 

public slots: 
    void addText(QString str) 
    { 
     edit->append(str); 
    } 

private: 
    QTextEdit* edit; 
    NetworkFile* net; 
}; 

class NetworkFile : public QObject 
{ 
    Q_OBJECT 

public: 
    NetworkFile(QObject *parent = 0): 
     QObject(parent) 
    { 
     connect(&server, &QTcpServer::newConnection, 
       this, &NetworkFile::newConnection); 
     //TODO: check return value 
     server.listen(QHostAddress::Any,16001); 
    } 

signals: 
    void dataRead(QString); 

public slots: 
    void newConnection(){ 
     //TODO: wire up socket disconnect with deleteLater, also check for null 
     QTcpSocket* socket = server.nextPendingConnection(); 
     connect(socket, &QTcpSocket::readyRead, 
       this, &NetworkFile::dataAvailable); 
    } 

    void dataAvailable(){ 
     //HACK: only for brevity, create a connection wrapper that contains the socket in real code 
     QTcpSocket* source = (QTcpSocket*)sender(); 

     auto bytes = source->readAll(); 
     if(bytes.size()) 
     { 
      emit dataRead(QString(bytes)); 
     } 
    } 

private: 
    QTcpServer server; 
}; 

#endif // MAINWINDOW_H 

CPP 파일

#include "mainwindow.h" 
#include <QApplication> 

MainWindow::MainWindow(QWidget *parent): 
    QMainWindow(parent) 
{ 
    edit = new QTextEdit(this); 
    net = new NetworkFile(this); 

    connect(net, &NetworkFile::dataRead, 
      this, &MainWindow::addText); 
    setCentralWidget(edit); 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 
+0

고마워요. 그러나 프로그램의 제어는 신호를 방출 한 후에 어디로 이동합니까? 나는 문자열을 어디서받을 것인가? –

+1

'connect (net, & NetworkFile :: dataRead, this, & MainWindow :: addText);'이렇게하면이 특정 인스턴스에서'dataRead'를 호출 할 때'addText'를 호출하게됩니다. 이벤트 루프에서). Qt를 사용한다면 신호/슬롯 시스템에 익숙해 져야합니다. – PeterT

+1

btw. connect (net, SIGNAL (dataRead), this, SLOT (addText));와 동일하지만 유형이 추가 된 connect (net, & NetworkFile :: dataRead, this, & MainWindow :: addText) - 컴파일시 검사. – PeterT

1

:

신호 [...] 창 형식 (즉, 사용 공극)을 가질 수 없다. 신호 (이 멤버 함수의 경우, 직접 즉 슬롯을 호출 할 때 당신은 여전히 ​​사용할 수 있지만)를 통해 호출 할 때

따라서 슬롯 반환 형식은 쓸모가 없습니다.

그런데 ui 또는 더 나은 plainLineEdit을 참조 또는 슬롯 (즉, 람다 인 경우)의 주소로 캡처하여 올바르게 문자열을 설정할 수 있습니다.

+0

감사합니다. 마지막 파라를 자세히 설명해 주시겠습니까? 예제에 의한 참조. –

+0

@PantherCoder 람다를 사용한 적이 있습니까? 나는'[& ui] (자동 ... args) {/ * 당신이 원하는 모든 것을 * /}'과 같은 것을 의미합니다. – skypjack

+0

아니요. 다른 방법으로'NetworkFile' 클래스에서'ui' 인스턴스를 사용할 수 있습니까? –