main 函数之2:noui_connect
// Connect bitcoind signal handlers
noui_connect();
说明是无界面情况(noui)下的信号连接
函数实现位于:Noui.cpp
void noui_connect()
{
// Connect bitcoind signal handlers
uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
uiInterface.ThreadSafeQuestion.connect(noui_ThreadSafeQuestion);
uiInterface.InitMessage.connect( noui_ThreadSafeQuestion );
}
PS:uiInterface 属于类CClientUIInterface, 类定义位于:ui_interface.h
ThreadSafeMessageBox、ThreadSafeQuestion、InitMessage 为CClientUIInterface 的三个成员变量,使用connect 方法连接到槽函数:noui_ThreadSafeMessageBox\noui_ThreadSafeQuestion\noui_ThreadSafeQuestion
这3个槽函数定义 :
/** Show message box. */
boost::signals2::signal<bool(const std::string& message, const std::string& caption, unsigned int style), boost::signals2::last_value> ThreadSafeMessageBox;
/** If possible, ask the user a question. If not, falls back to ThreadSafeMessageBox(noninteractive_message, caption, style) and returns false. */ boost::signals2::signal> ThreadSafeQuestion;
/** Progress message during initialization. */
boost::signals2::signalInitMessage;
要理解noui_connec函数,需要了解下QT编程 信号与槽的概念:
信号与槽
信号和槽是QT编程的基础,简单介绍 下它的机制:
槽和普通的C++成员函数几乎一样——可以是虚函数;可以被重载;可以是公有的、保护的、私有的,也可以被其他C++成员函数直接调用;它们的参数可以 是任意类型。
唯一不同是:槽还可以 与信号连接在一起:这种情况下, 每当发射这个信号时,就会自动调用这个槽。
connect 语句:
connect(sender, SINGNAL(signal),receiver,SLOT(slot));
这里的sender 和receiver 是指向QObject 的指针,signal和slot 是不带参数的函数名。SIGNAL() 与 SLOT() 是转换信号与槽的宏。
特点:
一个信号可以连接多个槽
当信号发射时,会以不确定的顺序一个接一个的调用各个槽。
多个信号可以连接同一个槽
即无论是哪一个信号被发射,都会调用这个槽。
信号直接可以相互连接
发射第一个信号时,也会发射第二个信号。
连接可以被移除
这种情况用得比较少,因为在对象被删除时,Qt会自动移除与这个对象相关的所有连接。语法如下:
disconnect(sender,SIGNAL(signal), receiver,SLOT(slot));
观察者模式 Signals2
signals2基于Boost的另一个库signals,实现了线程安全的观察者模式。在signals2中,观察者模式被称为信号/插槽(signals and slots),它是一种函数回调机制,一个信号关联了多个插槽,当信号发出时,所有关联它的插槽都会被调用。
本程式中:
boost::signals2::signal<bool(const std::string& message, const std::string& caption, unsigned int style), boost::signals2::last_value> ThreadSafeMessageBox;
=>
ThreadSafeMessageBox (信号) 通过Connect方法, 连接了符合定义 为:bool(const std::string& message, const std::string& caption, unsigned int style), boost::signals2::last_value> 的槽函数:noui_ThreadSafeMessageBox
其函数实现位于Noui.cpp:
同样,可看 noui_ThreadSafeQuestion 和 noui_ThreadSafeQuestion的槽函数实现:
分别表示:无对话框时,打印输出消息类型(Error/Warning/Information)和消息内容 、忽略用户交互提示消息(与noui_ThreadSafeMessageBox 相同) 和 打印输出程序初始化过程的消息 :
一 :noui_ThreadSafeMessageBox
(Show message box. )
style bit30 置为0
根据style的信息,添加标题显示 "error"或“warning”或“Infromation”到caption输出
根据style bit30 的SECURE 信息,选择print Message 的方式
返回false
二:noui_ThreadSafeQuestion
(If possible, ask the user a question. If not, falls back to ThreadSafeMessageBox(noninteractive_message, caption, style) and returns false.)
询问,无询问时操作实现同noui_ThreadSafeMessageBox, 同时返回false.
三:
noui_InitMessage:
打印出初始化时的信息
参考:
C++ GUI QT4 编程
区块链研习社源码研读班 姝婧