6

編集: 信号/スロット/接続とは関係ありません。問題は、コンストラクターを呼び出すコンストラクターでした。

これを行うためのより良い方法があるかもしれません-私はそれらを聞くことに興味があります...

QLabel から派生した MyClass があります。派生クラスに関するデータを、ベース シグナルよりも多くのデータをシグナルに戻したいと考えています。そこで、customContextMenuRequested シグナルをインターセプトし、より多くのデータを含む改訂版を発行するスロットを作成しました。

コンストラクターでこのシグナルを接続しようとすると、スロットが呼び出されません。しかし、ポリシーを移動し、行を親ウィジェット (クラス階層の親ではない) に接続して、MyClass が完全に構築された後に実行されるようにすると、私のスロットが呼び出されます。しかし、私は常にそれがこのクラスに接続されることを望んでおり、親クラスがそれを行うことを覚えていることを期待するのではなく、コンストラクターで望んでいるように思えます。

私が間違っていることはありますか?または、信号にデータを追加するより良い方法はありますか?

MyClass::MyClass() : QLabel()
{
    QFont currFont = font();
    currFont.setPointSize(15);
    setFont(currFont);

    setBackgroundRole(QPalette::Mid);

    std::cout << "connecting customContextMenuRequested" << std::endl;
    /** PROBLEM START */
    setContextMenuPolicy(Qt::CustomContextMenu);

    // Is there anything wrong with connecting from "this" to "this" in a constructor?

    QObject::connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
                     this, SLOT(addCellDataToMenuContextRequest(const QPoint&)));
     /* PROBLEM END **/
}


MyClass::MyClass(QString &cellString, int row, int col)
    : QLabel(cellString)
{
    MyClass();
    setRow(row);
    setCol(col);

}

// This one is a slot
void MyClass::addCellDataToMenuContextRequest(const QPoint& pos)
{
        // This doesn't get printed if I connect in my constructor,
        // but it does print if I do the same connect from a parent widget.
    std::cout << "called addCellDataToMenuContextRequest" << std::endl;

    emit customContextMenuRequestedForCell(pos, _row, _col);
}

したがって、親ウィジェットに customContextMenuRequestedForCell を探すだけにしてもらいたいのですが、現在、親ウィジェットは customContextMenuRequested も担当する必要があるようです。

4

2 に答える 2

5

実際、C++11 を使用している場合は、別のコンストラクターを呼び出すことができます。これは委譲コンストラクターと呼ばれます。しかし、それで問題が解決するとは思えません。あなたの問題は、呼び出されたときにメタオブジェクトが完全に構築されていないようconnect()です。また、C++11 を機能させるには、おそらく Qt 5 に移行する必要があります。

解決策は、オブジェクトが完全に構築されるまで接続を遅らせることです。ゼロの間隔でタイマーを開始できます。オブジェクトが完全に構築された後に確実に行われる次のイベントループ処理でトリガーされます。

次に、timerEvent で接続を確立し、タイマーを強制終了します。

編集:あなたの編集が表示されませんでした。解決策を見つけたようです。これは無視してください。:)

ところで。別のコンストラクターを呼び出していません。一時的な MyClass オブジェクトを作成しました。

于 2012-07-25T02:28:20.827 に答える
0

これを「よりクリーン」にする方法は、MyClass 内で QWidget::mouseReleaseEvent() を再実装することです。これを実装する方法は、mouseReleaseEvent に渡された QMouseEvent タイプがマウスの右クリックによるリリースでない場合、QLabel::mouseReleaseEvent(event) を呼び出すことです。右クリックのマウス リリース イベントの場合は、カスタム シグナルを送信できます。これにより、QLabel/QWidget によって提供される既存のマウス ボタン リリース処理コードを使用する利点が得られますが、カスタム シグナルを発したい 1 つのケースを傍受することができます。

EDITああ、mouseReleaseEvent がカスタム ケースを処理した後、必ず event->accept() を呼び出してください。

于 2012-07-25T02:35:54.437 に答える