1

このコードが機能しない理由がわかりません。SIGNAL と SLOT の概念を理解していない可能性があります。

例: という名前のMainWindowクラスがあり、このクラスには ui コンポーネントが含まれています。この UI では、ローカル サーバーを起動およびシャットダウンできます。このサーバーは class で定義されていますMyServerMainWindowクラスには への参照がありますMyServer class '&myServer'。クラスmainwindow.cppでこれを行うと、動作します:

connect(ui->startServer,SIGNAL(clicked()),&myServer,SLOT(startServer()));
connect(ui->shutdownServer,SIGNAL(clicked()),&myServer,SLOT(shutDownServer()));

しかし、この行はそうではありません:

connect(&myServer,SIGNAL(signalMessage()), this, SLOT(slotUpdate()));

この問題は次のとおりです。void signalMessage();MyServer クラスで名前が付けられたシグナルがあります。このシグナルは関数で呼び出されvoid startServer();void shutDownServer()

signals:
    void signalMessage();

通常、クラス内で呼び出した後singalMessage()MyServerクラス内の関数slotUpdate()を呼び出すMainWindow必要があります。しかし、 のみsignalMessage()が呼び出され、 は呼び出されませんslotUpadate()

誰かが私の問題を理解してくれることを願っています。MainWindow から MyServer へのスロットとシグナルを定義できますが、逆にすることはできません。:(

編集:わかりました、ここに私の問題を理解するためのいくつかのコードがあります:

メインウィンドウ.h

...
public:
    Ui::MainWindow *ui;
    MyServer myServer;


public slots:
    void slotUpdate();
...

メインウィンドウ.cpp

...
connect(ui->startServer,SIGNAL(clicked()),&myServer,SLOT(startServer()));
connect(ui->shutdownServer,SIGNAL(clicked()),&myServer,SLOT(shutDownServer()));
connect(&myServer,SIGNAL(signalMessage()), this, SLOT(slotUpdate()));
...
void MainWindow::slotUpdate()
{
    qDebug()<< "update()";
}
...

myserver.h

public slots:
void startServer();//start the server on 127.0.0.1 port: 1234
void shutDownServer();//disconnect threads, shut down server

signals:
    void signalMessage();

myserver.cpp

...
void MyServer::startServer(){
if(!this->listen(QHostAddress::Any,1234)){
    message.append("Could not start server, because server is already running");
}else{
    message.append("Listening...");
}

emit signalMessage();
}

...
void MyServer::signalMessage()
{
  qDebug() << "getMessage()";
}
4

4 に答える 4

2

信号を送受信するには:

  1. クラスは QObject から派生している必要があります。
  2. クラスの宣言内に Q_OBJECT マクロを含める必要があります。
  3. このクラスのヘッダー ファイルは moc で処理する必要があります (qmake を使用してプロジェクト ファイルを生成すると、自動的に処理されます)。

トラブルシューティング:

  1. ヘッダーに元々シグナル/スロットを含むクラスがなく、それらを追加した場合は、qmake を再実行して Makefile (または Visual Studio プロジェクト ファイル) を再生成する必要があります。
  2. プログラムのデバッグ バージョンをコンソール アプリケーション ( CONFIG += console*.pro ファイル内) としてビルドするか、プログラムの実行時にデバッグ出力を読み取ります。タイプミスをして qt がシグナルに接続できない場合、この問題に関するメッセージがデバッグ出力ウィンドウまたは stdout/stderr に出力されます。これが、接続の確立に失敗したことを通知する唯一の方法です。接続は、コンパイル時ではなく、アプリケーションの実行時 (実行時) に確立されます。
  3. Q_OBJECT をクラス宣言に追加するのを忘れた場合、または moc を介して (シグナル/スロットを持つクラスで) ヘッダーを実行しなかった場合、シグナル/スロットに接続できません。

シグナルの関数本体を記述する必要はありません。関数本体を記述する必要がある場合は、コードに問題があります。

また
、Qt には優れたドキュメントがあるので、それを読む 必要があります。qt をインストールした場合、ドキュメントは「アシスタント」プログラムを介して利用できるはずであり、オンラインでも利用できます

于 2013-07-01T13:52:25.247 に答える
1

関数を定義する必要がある場合は、クラス定義でマクロをsignalMessage使用しなかったことを意味します。Q_OBJECTMyServer

于 2013-07-01T13:27:59.880 に答える
1

ソリューション:

@アルネ:

「ソース ファイルで関数の実装を提供しました。つまり、void MyServer::signalMessage() { qDebug() << "getMessage()"; }。それは正しくありません。」

「接続ステートメントはすでに正しいです。サーバーが他の信号を受信するという事実は、QOBJECT マクロがそこにあることを示しています。関数の実装、つまり以前のコメントで引用したコード (cpp ファイルから) を削除してください」

したがってsingalMessage();、.cpp ファイルの実装を削除する必要があります。この後に connect(&myServer, SIGNAL(singalMessage()), this, SLOT(slotUpdate())); という行があります。動作します。

于 2013-07-01T14:02:24.083 に答える
0

signalMessageファイルで行ったように、自分で実装してはなりませんmyserver.cpp。このようにして、からのものQObjectはオーバーライドされ、シグナルは送信されません。

于 2013-07-01T13:25:59.890 に答える