4

folloginUIがあるとしましょう。

+--------------------------+
|W1       +--------------+ |
|         |W2            | |
|         | +----------+ | |
|         | |W3        | | |
|         | +----------+ | |
|         |              | |
|         +--------------+ |
+--------------------------+

W3は、W1(またはそれより下のレベル、つまりqApp)で放出される特定の信号に関心があります。

アイデアは、W3を独立して開発することです。しかし、誰かが信号/スロット接続を行う必要があります。

W3が他のウィジェットについて知らないようにし、W1がW3についても知らないようにする場合、W1で送信された信号をW3のスロットに接続するための良い方法/推奨される方法は何でしょうか?

解決策1:W1の信号をW2の信号に接続し(信号間技術)、したがってW2の信号をW3のスロットに接続します。

解決策2:qApp信号を生成し、W2でW3のスロットに接続します。

解決策3:qApp信号を生成し、W3自体が独自のスロットを使用してそれに接続するようにします。

ありがとう

4

3 に答える 3

4

通常、囲んでいるウィジェットはその中にウィジェットをカプセル化し、より高いレベルのインターフェースを提供します。たとえば、W3にいくつかの状態に応じて有効化/無効化する必要のあるウィジェットがいくつか含まれている場合、W3はその状態を管理し、APIを提供し、それに応じてウィジェットを有効化/無効化します。したがって、通常、W1からW3に直接移動する必要はありません。

ウィジェットがお互いを知らない場合(たとえば、b / c W1は何でも埋め込むことができる汎用コンテナウィジェットです)、UIをアセンブルし、関連するすべてのウィジェットを知っている人が接続を行う必要があります。

「qApp信号」の意味はわかりませんが、中央のオブジェクトがすべてに接続されているように聞こえます。もちろん、これも適切な設計ではありません。

多分あなたはあなたが考えていた特定の例を持っていますか?

于 2010-08-03T20:46:35.963 に答える
2

ここで使用するアプローチは、「シェル」が接続を確立することです。

シェルは、関連するすべてのウィジェットを認識しているオブジェクトです。この場合、W1、W2、およびW3です。通常、ユーザーインターフェイスをアセンブルするのはコードです。

シェルがW3について知らない場合(たとえば、W3は実装の詳細であるため)、W3の「所有者」は接続を行う必要があります。

于 2010-08-03T18:50:53.150 に答える
0

ウィジェットに名前を設定して、どこでもそれらを見つけることができます。

for(auto w_ptr: qApp->allWidgets())
    if(w_ptr->objectName() == "QObject anywhere")
        connect(...)

または親ウィジェット内:

if(QPushButton* o = findChild<QPushButton*>("QPushButton with name"))
    connect(...)

main.cpp

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

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

    QWidget wdgt;
    wdgt.setWindowTitle("wdgt");
    wdgt.setObjectName("wdgt");
    wdgt.show();

    Widget w;
    w.show();

    return a.exec();
}

widget.cpp

#include <qlayout>
#include <qpushButton>
#include <qdebug>
#include <qapplication>

#include "widget.h"
#include "connect_by_name.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("Widget");

    m_label->setFrameShape(QFrame::Box);

    QHBoxLayout * hl{new QHBoxLayout{}};

    hl->addWidget(m_label);
    hl->addWidget(new connect_by_name{});
    setLayout(hl);

    connect_to_unique_pb();
}

void Widget
::connect_to_unique_pb() {
    if(QPushButton * pb_ptr
            = findChild<QPushButton*>("unique_pb"))
    {
        connect(pb_ptr,  &QPushButton::pressed,
                m_label, &QLabel::clear);
        connect(pb_ptr,  &QPushButton::released,
                this,    &Widget::pb_relased);
    }
    else
    {
        qDebug() << "The push button not found.";
    }
}

void Widget
::pb_relased() {
    m_label->setText("button not pressed");
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <qwidget>
#include <QLabel>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);

public slots:
    void pb_relased();

private:
    void connect_to_unique_pb();

private:
    QLabel * m_label{new QLabel{"button not pressed"}};
};

#endif // WIDGET_H

connect_by_name.cpp

#include <qapplication>
#include <qdebug>
#include <qwidget>

#include "connect_by_name.h"
#include "widget.h"

connect_by_name
::connect_by_name(QWidget *parent) :
    QWidget(parent)
{
    m_pb->setObjectName("unique_pb");
    m_hl->addWidget(m_pb);
    connect_to_unique_widget();
}

void connect_by_name
::connect_to_unique_widget() {
    for(auto w_ptr: qApp->allWidgets())
        if(w_ptr->objectName() == "wdgt") {
            connect(m_pb,  &QPushButton::pressed,
                    w_ptr, &QWidget::hide);
            connect(m_pb,  &QPushButton::released,
                    w_ptr, &QWidget::show);
            break;
        }
}

connect_by_name.h

#ifndef CONNECT_BY_NAME_H
#define CONNECT_BY_NAME_H

#include <QWidget>
#include <QPushButton>
#include <QLayout>

class connect_by_name : public QWidget
{
    Q_OBJECT

public:
    explicit connect_by_name(QWidget *parent = nullptr);

private:
    void connect_to_unique_widget();

private:
    QHBoxLayout * m_hl {new QHBoxLayout{this}};
    QPushButton * m_pb {new QPushButton{"unique button"}};
};

#endif // CONNECT_BY_NAME_H

connect.pro

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET   = connect
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp \
        widget.cpp \
        connect_by_name.cpp

HEADERS += \
        widget.h \
        connect_by_name.h
于 2019-02-07T15:48:06.137 に答える