web-dev-qa-db-ja.com

信号とスロットを異なる引数で接続するにはどうすればよいですか?

Qtでは、シグナルとスロットは一致する引数タイプを必要とします。

QObject :: connect:互換性のない送信者/受信者引数QLabel :: linkActivated(QString)-> Button :: call(int)

このような組み合わせを実装するにはどうすればよいですか?

15
user896036

簡単な方法は、必要なスロットを呼び出す中間スロットを用意することです。例えば.

connect(src, SIGNAL(linkActivated(QString)), this, SLOT(receiveLink(QString)));

その後

void receiveLink(QString blah)
{
  int response = someFunction(blah);
  mybutton->call(response);
}

文字列をintに解釈する方法を定義する必要があります。

18
koan

シグナルスロットのドキュメント から:

信号の署名は、受信スロットの署名と一致する必要があります。 (実際、スロットは余分な引数を無視できるため、受信する信号よりも署名が短い場合があります。)

これは、次の形式の信号を意味します

signal(int, int, QString

次の署名のあるスロットにのみ接続できます

slot1(int, int, QString)
slot2(int, int)
slot3(int)
slot4()

Koanが示唆しているように、最善のアプローチは、QString引数を持つ別のスロットを使用してから、実際に必要なスロットを呼び出すことです。

34
pnezis

スロットパラメータのデフォルト値は非常に役立ちます。これにより、異なる署名の信号をスロットに接続できます(@pnezis回答の場合はその逆)。

private slots:
  void slot( int x = 10, int y = 20, QString text = QString() );

異なる信号に接続できます:

signal1(int, int, QString)
signal2(int, int)
signal3(int)
signal4()

また、Qt 4.8は便利なことを示唆しています QSignalMapper class:

このクラスは、パラメーターのないシグナルのセットを収集し、シグナルを送信したオブジェクトに対応する整数、文字列、またはウィジェットのパラメーターを使用してそれらを再発行します。

ただし、1つのパラメーターのみ:

QSignalMapper* mapper = new QSignalMapper(this) ;

connect(action, SIGNAL(triggered()), mapper, SLOT(map())) ;
mapper->setMapping(action, "param value") ;

connect(mapper, SIGNAL(mapped(const QString &)),
  this, SIGNAL(clicked(const QString &)));
4
oklas

補足的な答えとして、中間スロットを作成したくない場合は、ラムダ式を使用して(もちろん、C++ 11サポートを使用して)メソッドを呼び出すことができます。ただし、コネクタクラスは、これらの特定の信号およびスロットで使用されるパラメータタイプを認識している必要があります。

例を挙げると、パラメータタイプがQStringの信号を、パラメータタイプがcharのスロットに接続しようとしているとすると、次のようになります。

class SignalClass{
signals:
    void testSignal(QString tString);
};

class SlotClass{
public slots:
    void testSlot(char tChar);
};

class ConnectorClass{
public:
    void connectSignalAndSlot () {
        SignalClass tSigClass;
        SlotClass tSlotClass;
        connect(&tSigClass, &SignalClass::testSignal,
                [=](QString tString) { this->metaObject()->invokeMethod(tSlotClass,"testSlot", Q_ARG(char, tString.at(0).toLatin1())) }
        );
    }
}

ちょっと醜いものですが、仕事をします。

  • 結合されたクラスはありません
  • 中間コネクタ機能なし
0
benjamin button