0

QSplitter ウィジェット (他のウィジェットの中でも) を含むメイン ウィンドウ クラスがあります。このスプリッターのコンテンツは、別のクラスにあるウィジェットによって取り込まれます。

この他の Widgwt 内には、test_btn という QPushButton が追加されたレイアウトがありpublic slots:ます。また、cpp ファイルに対応するコードを持つ test_function というヘッダー ファイルで定義された関数もあります。

cout << "Test!" << endl;

次のコードを使用して、この関数を呼び出してみます。

connect(test_btn, SIGNAL(clicked()), SLOT(test_function()));

ウィジェットとボタンはアプリケーションで期待どおりに表示されますが、クリックしても何も起こりません。

connectメイン ウィンドウに同じコードを追加すると、機能します (メイン ウィンドウからテスト関数を呼び出す場合)。

connect(cc_point.test_btn, SIGNAL(clicked()), SLOT(main_win_test_function()));

から呼び出さない限り、他のクラスからテスト関数を呼び出すことはできませんmain_win_test_function()

メインウィンドウクラスではそれがなくても機能し、コンパイル時にエラーは発生しませんが、接続ステートメントから「レシーバーウィジェット」が欠落していることはわかっています。

で親または何かを定義する必要がありますother_classか?

main_window.cpp:

main_window::main_window()
{
    add_splitter();

    QGridLayout *window_layout = new QGridLayout;

    window_layout->setSpacing(0);
    window_layout->setContentsMargins(0, 0, 0, 0);

    window_layout->addWidget(splitter1, 0, 0);

    set_layout(window_layout);
}

void main_window::add_splitter()
{
     other_class oc_point;

     splitter1 = new QSplitter(Qt::Horizontal);

     splitter1->addWidget(oc_point.oc_widget);
}

other_class.cpp:

other_class:other_class()
{
     oc_widget = new QWidget;

     QGridLayout *other_layout = new QGridLayout(oc_widget);

     test_btn = new QPushButton;
     test_btn->setText("Test Button");

     connect(test_btn, SIGNAL(clicked()), test_btn->parent(), SLOT(test_function());
     other_layout->addWidget(test_btn);
}

void other_class::test_function()
{
     cout << "Test output" << endl;
}

main.cpp:

int main(int argc, char *argv[]) {

QApplication app(argc, argv);

main_window window;

window.resize(1100, 700);
window.setWindowTitle("Qt Test");
window.setWindowIcon(QIcon (":/images/icon_1.png"));
window.setMinimumHeight(500);
window.show();

return app.exec();
}

上で述べたように、ウィンドウが作成され、ウィジェットが表示される限り、これはすべて正常に機能しますが、ボタンをクリックしても test_function は呼び出されません。ヘッダー ファイルも含める必要がある場合はお知らせください。

4

2 に答える 2

0

オブジェクトを初期化したら、オブジェクトを相互に接続する必要があります。誰のスロットが誰で、誰の信号が誰であるかを明示的に指定すると、非常に役立ちます。

たまにヘルパー関数を作るvoid Widget::connectTo__Class__(Class * class_ptr);

次に、その関数呼び出しで、クラス/親/継承の境界を越えるスロットを接続します。

実装例を次に示します。

void Widget::connectTo__Class__(Class * class_ptr)
{
    QObject::connect(this,      SIGNAL(myWidgetSignal()), 
                     class_ptr, SLOT(myClassSlot()));

    QObject::connect(class_ptr, SIGNAL(myClassSignal()), 
                     this,      SLOT(myWidgetSlot()));
}

class_ptrまた、が存在するnull場合やmyClassSignal存在しない場合など、何か間違ったことをすると、ランタイムが文句を言うことに注意してください。これらのエラーは、アプリケーションをデバッグ モードで実行すると、出力に表示されます。

そしてQDebug、いつか挑戦してください。

http://qt-project.org/doc/qt-4.8/debug.html

編集: ヘッダー クラスの再帰的な定義の問題を修正するには、次の手順を実行します。

クラスの 1 つのヘッダー ファイルでは、クラスのプロトタイプのみを作成し、含めないでください。

widget.h で:

// #include "myclass.cpp" // Should be commented out!

class MyClass; // This prototype avoids the recursion

// ...

class Widget
{
    // ...

    public:
        void connectToMyClass(Class * class_ptr);

    // ...
}

次に、cpp ファイルでインクルードを行います。

#include "myclass.h"

void Widget::connectToMyClass(Class * class_ptr)
{
    // ...
}

この問題を回避する別の方法は、QObject *代わりに を使用することですClass *

それが役立つことを願っています。

于 2013-08-26T17:08:08.683 に答える