qt/bitcoin.h
pulls the config/bitcoin-config.h
definitions that were generated by the configure
script during the build process.
This header also contains the Qt Q_OBJECT
BitcoinCore
class which handles 3 signals and provides 2 slots.
(If you’re not familiar with Qt, please go here for an intro to slots and signals or here for an explanation about the Q_OBJECT macro.)
Slots, signals and Q_OBJECT in a nutshell
If you’re in a hurry, all you need to know is Qt slots and signals are the mechanism by which Qt does multithreading. Qt manages its own loop where it orchestrates how signals received are sent to slots for processing. This is unrelated to Bitcoin and specific to the GUI framework.
The Q_OBJECT macro is required by the Qt MOC (meta-object compiler) which generates some Qt-specific boilerplate code.
All the BitcoinCore
class does is hook the Bitcoin Core startup and shutdown procedures up to the Qt multithreading system.
The slots are aptly called initialize
and shutdown
. The class handles three signals: initializeResult
, shutdownResult
and runawayException
.
BitcoinApplication
The bitcoin.h
header then defines the BitcoinApplication
class, which is also a Qt Q_OBJECT
class that extends QApplication
. As you may infer, this is the main Qt application class, which will run for as long as the graphical Bitcoin Core program is open.
For all practical purposes the BitcoinApplication
class encapsulates what a console application’s main
function does : it wraps the Qt program from start to finish. BitcoinApplication
is the thing you see when you run bitcoin-qt
BitcoinApplication
encapsulates everything the Bitcoin Core graphical interface needs to run a full node, managing the following fields (field names in bold):
QThread *coreThread
– This separate thread will take care of application initialization, shutdown and exceptions. It’s connected to several signals on qt/bitcoin.cpp
.
interfaces::Node& m_node
– The Node class (defined in interfaces/node.h
) encapsulates the functionality of a bitcoind process. It does everything you expect a Bitcoin node to do including manage wallets, get BTC balances, activate and deactivate the network service, get blockchain data, ban network hosts and much more.
OptionsModel *optionsModel
– This class encapsulates 21 application options. It’s a QAbstractListModel
subclass. Options are passed in from the command line or from configuration files. This is where the application stores options like database cache, UPnP port mapping toggle, what language to use, network proxy information and much more.
ClientModel *clientModel
– The ClientModel class encapsulates Bitcoin networking functions in a Qt wrapper. It updates the Qt graphical user interface with data from the underlying Bitcoin network client.
BitcoinGUI *window
– This is the main QMainWindow
of the application. This is where all the user interaction handling happens.
Here are some of the actions handled by the
BitcoinGUI
window:QAction* overviewAction = nullptr; QAction* historyAction = nullptr; QAction* quitAction = nullptr; QAction* sendCoinsAction = nullptr; QAction* sendCoinsMenuAction = nullptr; QAction* usedSendingAddressesAction = nullptr; QAction* usedReceivingAddressesAction = nullptr; QAction* signMessageAction = nullptr; QAction* verifyMessageAction = nullptr; QAction* aboutAction = nullptr; QAction* receiveCoinsAction = nullptr; QAction* receiveCoinsMenuAction = nullptr; QAction* optionsAction = nullptr; QAction* toggleHideAction = nullptr; QAction* encryptWalletAction = nullptr; QAction* backupWalletAction = nullptr; QAction* changePassphraseAction = nullptr; QAction* aboutQtAction = nullptr; QAction* openRPCConsoleAction = nullptr; QAction* openAction = nullptr; QAction* showHelpMessageAction = nullptr; QAction* m_open_wallet_action{nullptr}; QMenu* m_open_wallet_menu{nullptr}; QAction* m_close_wallet_action{nullptr}; QAction* m_wallet_selector_label_action = nullptr; QAction* m_wallet_selector_action = nullptr;
Note:
QAction
‘s are user interface actions that the window must respond to. The names are intuitive and give us an idea of all the things handled byBitcoinGUI
.
QTimer *pollShutdownTimer
– This is a QTimer object that’s instantiated when BitcoinGUI
creates the main window. The timer gets started in the initializeResult
handler in qt/bitcoin.cpp
. When initialization is a success, the timer starts firing every 200 milliseconds throughout the lifetime of the Bitcoin client GUI, checking whether system shutdown has been requested from anywhere in the system. If any component of the system has requested shutdown, tested at BitcoinGUI::detectShutdown
, then the RPC console is hidden and the application is sent the quit()
message. This timer is the reason there’s a tiny lag between when you order the application shutdown and when it actually exits. All the messages are asynchronous.
Next up is a compilation-conditional block:
#ifdef ENABLE_WALLET
PaymentServer* paymentServer{nullptr};
WalletController* m_wallet_controller{nullptr};
#endif
The Bitcoin Core node can be compiled and run without a wallet in it! You can run a full verifying node without having a wallet. Such a node would contribute to the Bitcoin network, verifying and relaying transactions, but would not hold any coins nor perform any wallet-related functions (send/receive/check balance/etc).
If you compile Core with wallet functionality (default), then these two members are compiled into BitcoinGUI
:
PaymentServer* paymentServer{nullptr}
– This class handles payment requests when the user clicks on a Bitcoin link somewhere else in the operating system. Special care is taken to not handle such requests when the system isn’t in functional condition (starting up or shutting down, for example).
WalletController* m_wallet_controller{nullptr}
– This class handles messages back and forth between the user interface and the underlying Wallet class. It’s a controller class that glues together Wallet
‘s, the Node
and the user interface.
int returnValue
– This value is passed between BitcoinCore
and BitcoinApplication
classes through a Qt slot/signal connection. When BitcoinCore
finishes initializing, it sends a signal which is handled by BitcoinApplication
. returnValue
is then checked. If all went well in the initialization, then BitcoinApplication
starts running. Else the program exits.
const PlatformStyle *platformStyle
– A class that encapsulates Windows, MAC OS X and “other” platform-specific settings. This controls icons on buttons and other GUI details for each platform.
std::unique_ptr<QWidget> shutdownWindow
– This is a pointer to a QWidget dialog (or window) that is displayed when system shutdown is requested. As mentioned before, shutdown is asynchronous, so this little window sticks around while the rest of the system cleans up and exits. A bit more detail is given in the pollShutdownTimer
section above.
Lastly on qt/bitcoin.h
the GuiMain
subroutine is declared:
int GuiMain(int argc, char* argv[]);
GuiMain
is called from main(int argc, char* argv[]
) which is discussed in the qt/main.cpp
article.
(In fact GuiMain
is the only thing main()
does in bitcoin-qt
. It’s a one liner.)