比方说,我们有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本身连接使用它自己的插槽它。
谢谢
通常封闭插件封装里面的小部件,并提供了更高级别的接口。例如,如果W3包含需要启用/禁用根据一些国家的几个小部件,W3将管理该状态,因为它提供的API,并相应地启用/禁用部件。所以通常没有必要直接从W1去W3。
如果小部件不知道对方的存在(如B / C W1是一个通用的容器小部件,可以嵌入任何东西),那么谁组装UI,知道所有涉及的部件之一,应该做的连接。
我不知道你所说的“qApp信号”的意思,但听起来太像中央物体被连接到的一切,当然这是不好的设计,无论是。
也许你有你的想法有一个具体的例子吗?
我们在这里使用的方法是“壳”,使连接。
外壳是知道的所有相关部件的对象。在这种情况下,W1,W2和W3。通常它是组装用户接口的代码。
如果shell不知道W3(W3因为是一个实现细节,例如),然后W3的“拥有者”应使连接等。
您可以设置名称的小部件,然后发现他们的任何地方:
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