信号和槽在多层UI部件

问题描述 投票:2回答:3

比方说,我们有follogin UI:

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

W3是有意在W1发射某一信号(或以下的水平,即qApp)。

我们的想法是独立开发W3。但被人做信号/槽连接。

什么是连接在W1排放到插槽W3如果我们想W3不知道任何其他插件的信号的良好做法/推荐的方式,而我们不希望W1知道W3要么?

解决方案1:在与W1信号W2连接信号(信号到信号技术),并且因此在连接W2信号W3到插槽。

溶液2:产生qApp信号,并将其在与W2插槽W3连接。

解决方法3:生成qApp信号,并W3本身连接使用它自己的插槽它。

谢谢

qt user-interface signals slot
3个回答
3
投票

通常封闭插件封装里面的小部件,并提供了更高级别的接口。例如,如果W3包含需要启用/禁用根据一些国家的几个小部件,W3将管理该状态,因为它提供的API,并相应地启用/禁用部件。所以通常没有必要直接从W1去W3。

如果小部件不知道对方的存在(如B / C W1是一个通用的容器小部件,可以嵌入任何东西),那么谁组装UI,知道所有涉及的部件之一,应该做的连接。

我不知道你所说的“qApp信号”的意思,但听起来太像中央物体被连接到的一切,当然这是不好的设计,无论是。

也许你有你的想法有一个具体的例子吗?


1
投票

我们在这里使用的方法是“壳”,使连接。

外壳是知道的所有相关部件的对象。在这种情况下,W1,W2和W3。通常它是组装用户接口的代码。

如果shell不知道W3(W3因为是一个实现细节,例如),然后W3的“拥有者”应使连接等。


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
© www.soinside.com 2019 - 2024. All rights reserved.