Con tu cerebro y tu conexión a internet me dices que hace esta página de código de Bitcoin Core. Ya que sólo necesitas eso para comprender todo el código de BTC, no creo que esto te suponga un problema... (una página de nada, de las miles que hay)
int GuiMain(int argc, char* argv[]) { > Compile-time conditional checks for Windows32 API: > If being compiled on Windows, uses the WinCmdLineArgs from util/system.h > to return a std:
😛air<int, char**> via the get() method. > While std::tie(argc, argv) may look intuitive to python programmers, > in C++ you need a function to turn a rvalue tuple (a,b) into > lvalues that you can assign to. That's what std:tie() does here. #ifdef WIN32 util::WinCmdLineArgs winArgs; std::tie(argc, argv) = winArgs.get(); #endif > SetupEnvironment() sets up memory allocation and locale. > It starts by configuring the memory allocator so that 32 bit systems only > use one memory arena per core. It then sets the locale for POSIX systems. > On Windows it sets the charset to UTF8. SetupEnvironment(); > ThreadRename(std::string name) calls into util/threadnames.cpp and sets > the current thread name to name. On linux it uses prctl, on *BSD it > calls pthread_set_name_np and on MacOSX it calls pthread_setname_np util::ThreadRename("main"); > Instantiates interfaces::Node using the interfaces::MakeNode() factory > method. A Node is an interface offered by the Bitcoin node. Same thing > that bitcoind does as a daemon offering an entry point to several services. std::unique_ptr<interfaces::Node> node = interfaces::MakeNode(); > Here several pointers to event handlers are instantiated to handle > user interface signals. The boost::signals2 library is used to handle these. > interfaces::Handler is just a thin wrapper around boost::signals2::connection std::unique_ptr<interfaces::Handler> handler_message_box = node->handleMessageBox(noui_ThreadSafeMessageBox); std::unique_ptr<interfaces::Handler> handler_question = node->handleQuestion(noui_ThreadSafeQuestion); std::unique_ptr<interfaces::Handler> handler_init_message = node->handleInitMessage(noui_InitMessage); > Qt-specific GUI settings are applied. Check the Qt documentation. // Do not refer to data directory yet, this can be overridden by Intro:
😛ickDataDirectory /// 1. Basic Qt initialization (not dependent on parameters or configuration) Q_INIT_RESOURCE(bitcoin); Q_INIT_RESOURCE(bitcoin_locale); // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #if QT_VERSION >= 0x050600 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif > The main BitcoinApplication is created. The node pointer that was instantiated earlier > is passed as a parameter. BitcoinApplication class is discussed in qt/bitcoin.h. > BitcoinApplication is a Qt QApplication derived class. The constructor receiving a Node is > customized. BitcoinApplication app(*node); > Here several object types are registered with the Qt system so they can > receive asynchronous calls. Messages from the Bitcoin subsystem can > arrive at any time. So the notifications and GUI updates are made async. // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); #ifdef ENABLE_WALLET qRegisterMetaType<WalletModel*>(); #endif // Need to pass name here as CAmount is a typedef (see
Tienes que estar registrado para ver este contenido
) // IMPORTANT if it is no longer a typedef use the normal variant above qRegisterMetaType< CAmount >("CAmount"); qRegisterMetaType< std::function<void()> >("std::function<void()>"); qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon"); > setupServerArgs() calls into SetupServerArgs() at init.cpp > This helper function parses the command line and updates the global gArgs object > Not much to comment on here, check out init.cpp for the specific options it processes. > SetupUIArgs() does something similar, except for user interface command line options. > SetupUIArgs() is defined in this same source file, check the implementation for details. /// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these // Command-line options take precedence: node->setupServerArgs(); SetupUIArgs(); std::string error; if (!node->parseParameters(argc, argv, error)) { node->initError(strprintf("Error parsing command line arguments: %sn", error)); // Create a message box, because the gui has neither been created nor has subscribed to core signals QMessageBox::critical(nullptr, PACKAGE_NAME, // message can not be translated because translations have not been initialized QString::fromStdString("Error parsing command line arguments: %1.").arg(QString::fromStdString(error))); return EXIT_FAILURE; } > Platform style has been discussed in the qt/bitcoin.h header post. > It basically sets some GUI specifics for MAC, WIN and "other" (Linux, etc). > e.g. Icons on buttons and other visual details are set via the platform style. // Now that the QApplication is setup and we have parsed our parameters, we can set the platform style app.setupPlatformStyle(); > Qt saves lots of global state. > In the trinc calls the Qt "options model" is configured with settings > which are later read by QSettings when performing several tasks. > QSettings is an abstraction of Windows Registry and similar local configs. > See
Tienes que estar registrado para ver este contenido
/// 3. Application identification // must be set before OptionsModel is initialized or translations are loaded, // as it is used to locate QSettings QApplication::setOrganizationName(QAPP_ORG_NAME); QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN); QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT); > Qt's internal language translation mechanism is set up > Not much to comment here, check Qt docs for details. /// 4. Initialization of translations, so that intro dialog is in user's language // Now that QSettings are accessible, initialize translations QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator); > If user requested -help on the command line then allow HelpMessageDialog class to decide whether to > show a GUI dialog box or print out help data on the console. HelpMessageDialog is implemented > in qt/utilitydialog.h // Show help message immediately after parsing command-line options (for "-lang") and setting locale, // but before showing splash screen. if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { HelpMessageDialog help(*node, nullptr, gArgs.IsArgSet("-version")); help.showOrPrint(); return EXIT_SUCCESS; } > The Intro class is defined in qt/intro.h and implemented in qt/intro.cpp > pickDataDirectory checks for a -datadir option passed on the command line > It then tries to read a default datadir via GUIUtil::getDefaultDataDirectory() > If the data dir is not found, it enters a loop that exists only when cancelled > or a valid data directory is chosen. > After the data dir is set, it updates global settings strDataDir and fReset and moves on > reading config and data files in the configured directory. /// 5. Now that settings and translations are available, ask user for data directory // User language is set up: pick a data directory if (!Intro:
😛ickDataDirectory(*node)) return EXIT_SUCCESS; /// 6. Determine availability of data directory and parse bitcoin.conf /// - Do not call GetDataDir(true) before this step finishes if (!CheckDataDirOption()) { node->initError(strprintf("Specified data directory "%s" does not exist.n", gArgs.GetArg("-datadir", ""))); QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified data directory "%1" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", "")))); return EXIT_FAILURE; } if (!node->readConfigFiles(error)) { node->initError(strprintf("Error reading configuration file: %sn", error)); QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error))); return EXIT_FAILURE; } /// 7. Determine network (and switch to network specific options) // - Do not call Params() before this step // - Do this after parsing the configuration file, as the network can be switched there // - QSettings() will use the new application name after this, resulting in network-specific settings // - Needs to be done before createOptionsModel > Select Bitcoin network. > Check Bitcoin wiki for info on Bitcoin network specifics. // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) try { node->selectParams(gArgs.GetChainName()); } catch(std::exception &e) { node->initError(strprintf("%sn", e.what())); QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: %1").arg(e.what())); return EXIT_FAILURE; } > The PaymentServer handles Bitcoin urls clicked on or passed via command line. > During initialization it checks if any Bitcoin URLs were passed on the command line. > It then starts the PaymentServer to handle Bitcoin links as the program runs. > The whole trinc section deals with PaymentServer and command line URL parsing. #ifdef ENABLE_WALLET // Parse URIs on command line -- this can affect Params() PaymentServer::ipcParseCommandLine(*node, argc, argv); #endif QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString()))); assert(!networkStyle.isNull()); // Allow for separate UI settings for testnets QApplication::setApplicationName(networkStyle->getAppName()); // Re-initialize translations after changing application name (language in network-specific settings can be different) initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator); #ifdef ENABLE_WALLET /// 8. URI IPC sending // - Do this early as we don't want to bother initializing if we are just calling IPC // - Do this *after* setting up the data directory, as the data directory hash is used in the name // of the server. // - Do this after creating app and setting up translations, so errors are // translated properly. if (PaymentServer::ipcSendCommandLine()) exit(EXIT_SUCCESS); // Start up the payment server early, too, so impatient users that click on // bitcoin: links repeatedly have their payment requests routed to this process: if (WalletModel::isWalletEnabled()) { app.createPaymentServer(); } #endif // ENABLE_WALLET > Set up Qt GUI. No bitcoin specifics to comment on here. /// 9. Main GUI initialization // Install global event filter that makes sure that long tooltips can be word-wrapped app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); #if defined(Q_OS_WIN) // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION) qApp->installNativeEventFilter(new WinShutdownMonitor()); #endif // Install qDebug() message handler to route to debug.log qInstallMessageHandler(DebugMessageHandler); // Allow parameter interaction before we create the options model app.parameterSetup(); // Load GUI settings from QSettings app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false)); if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false)) app.createSplashScreen(networkStyle.data()); int rv = EXIT_SUCCESS; try { app.createWindow(networkStyle.data()); // Perform base initialization before spinning up initialization/shutdown thread // This is acceptable because this function only contains steps that are quick to execute, // so the GUI thread won't be held up. if (app.baseInitialize()) { app.requestInitialize(); #if defined(Q_OS_WIN) WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(PACKAGE_NAME), (HWND)app.getMainWinId()); #endif > The exec() method of QApplication blocks until exit() is called in the application > After exec() returns, the requestShutdown() method executes, which resets the > shutdownWindow, hides the main window, disconnects signals, shuts the Node down > and stops pollShutdownTimer (discussed in qt/bitcoin.h) and finally fires > the requestedShutdown() signal. app.exec(); app.requestShutdown(); > Here the main event loop is restarted to allow the splash screen to show and for any remaining signals to be handled > including the requestedShutdown() which will trigger QWidget::close() app.exec(); > Finally the return value is captured into rv to be returned at the end of GuiMain > which in turn returns to main(). Therefore the rv return value will end up as > the operating system's return value. rv = app.getReturnValue(); } else { // A dialog with detailed error will have been shown by InitError() rv = EXIT_FAILURE; } } catch (const std::exception& e) { PrintExceptionContinue(&e, "Runaway exception"); app.handleRunawayException(QString::fromStdString(node->getWarnings("gui"))); } catch (...) { PrintExceptionContinue(nullptr, "Runaway exception"); app.handleRunawayException(QString::fromStdString(node->getWarnings("gui"))); } return rv; }