这里主要分析QtCreator中OutputPane的相关内容,能够看到QtCreator在状态栏有四个Checkable按钮,以下图所示app
checkable按钮的实现方式基本一致,这里仅以其中一种General Message来讲明问题。在插件源码的coreplugin中,相关类有ModeManager,MessageManager,MessageOutputWindow,OutputPaneManager,OutputPaneToggleButton,OutputPaneManageButton,OutputPanePlaceHolder,MiniSplitterHandle,OutputWindow以及StatusBarManager和StatusBarWidget。这里首先看一下他们之间的关系。ide
接下来详细解释与分析一下(高手勿喷,请多指教)。函数
MainWindow应该作的都只是各类管理器的初始化工做,如何布局是由ModeManager来管理的,ModeManager经过各个不一样的Mode来呈现不一样的界面布局。工具
IMode就是这些Mode的接口类,在后面会详细介绍。先看MainWindow,初始化分为了三个部分:构造函数、init()、extensionsInitialized()。在Qt Creator中,不少Manager使用单例模式,可是这些单例模式能够说是一种不自动的,没有根据成员m_instance的状态来判断是建立实例仍是直接返回,每个Manager都须要create一下(好处不详,没有分析出来,望高手赐教)。在构造函数中就是调用这些create(),合情合理,构造函数不就是建立嘛。先上段代码看看:布局
MainWindow::MainWindow() : Utils::AppMainWindow(), m_coreImpl(new ICore(this)), ..... m_actionManager(new ActionManager(this)), m_editorManager(0), ..... m_statusBarManager(0), m_modeManager(0), ..... m_activeContext(0), m_generalSettings(new GeneralSettings), m_shortcutSettings(new ShortcutSettings), ..... m_toggleSideBarAction(0), ..... m_toggleSideBarButton(new QToolButton) { (void) new DocumentManager(this); OutputPaneManager::create(); setWindowTitle(tr("Qt Creator")); ...... ...... registerDefaultContainers(); registerDefaultActions(); ...... m_modeStack = new FancyTabWidget(this); m_modeManager = new ModeManager(this, m_modeStack); m_modeManager->addWidget(m_progressManager->progressView()); m_statusBarManager = new StatusBarManager(this); m_messageManager = new MessageManager; m_editorManager = new EditorManager(this); m_editorManager->hide(); m_externalToolManager = new ExternalToolManager(); setCentralWidget(m_modeStack); ....... statusBar()->insertPermanentWidget(0, m_toggleSideBarButton); ....... }
撇掉与输出窗口无关的东西,上面的代码就是与Output相关的代码。this
m_actionManager用于管理菜单,关于Output仅用于注册快捷键。 .net
完成OutputPaneManager建立,在其构造函数中添加了“清除action”,“prevAction”,“nextAction”,”最大化最小化”,”关闭“等输出窗口上toolbar的一些action。这几个action是全部输出类窗口的公共action,也就是说,全部的输出类窗口都会有这几个action。插件
用于添加主窗口的菜单,具体添加方法参见http://www.devbean.info/2012/03/qtcreator-plugin-develop-catalog/设计
FancyTabWidget是Qt Creator窗口最左边的一列,包括欢迎、编辑、调试、设计、项目、分析、帮助,下边还有一个你们都熟悉的cornerWidget(放着构建、构建运行等几个按钮)。ModeManager用于管理各类Mode,好比EditMode,WelcomeMode等等,每个FancyTabWidget中的Tab对应一个Mode,从这里能够看出,能够经过添加IMode的子类以在FancyTabWidget中添加Tab。ModeManager的构造函数完成FancyTabWidget的Tab改变所引发的信号的槽,并添加cornerWidget(在FancyTabWidget中,并无添加,只是添加了一个占位的布局而已)。调试
StatusBarManager的构造函数完成根据StatusBarWidget的个数(四个)向StatusBar添加Widget的功能(其实就至关于将状态栏分红了四个部分),并将他们存放在QList<QWidget*>中以便之后使用。来一段代码
StatusBarManager::StatusBarManager(MainWindow *mainWnd) : QObject(mainWnd), m_mainWnd(mainWnd) { for (int i = 0; i <= StatusBarWidget::Last; ++i) { QWidget *w = new QWidget(); m_mainWnd->statusBar()->insertPermanentWidget(i, w); w->setLayout(new QHBoxLayout); w->setVisible(true); w->layout()->setMargin(0); m_statusBarWidgets.append(w); } m_mainWnd->statusBar()->insertPermanentWidget(StatusBarWidget::Last+1, new QLabel(), 1); }
我的认为这里使得状态栏的分组个数固定,设计并非很好,插件但愿添加按钮到状态栏时就遇到了困难,须要修改StatusBarWidget,并从新编译Core插件,不知道是我理解的不够深刻仍是怎么。MessageManager的构造函数并无作什么实质性的东西。
statusBar()->insertPermanentWidget(0, m_toggleSideBarButton);在状态栏的最左边添加了一个按钮用于显示/隐藏边栏。
先上代码,已经去掉无关代码。
bool MainWindow::init(QString *errorMessage) { Q_UNUSED(errorMessage) ..... ExtensionSystem::PluginManager::addObject(m_coreImpl); m_statusBarManager->init(); m_modeManager->init(); ....... m_outputView = new Core::StatusBarWidget; m_outputView->setWidget(OutputPaneManager::instance()->buttonsWidget()); m_outputView->setPosition(Core::StatusBarWidget::Second); ExtensionSystem::PluginManager::addObject(m_outputView); m_messageManager->init(); return true; }
仅将对象池的objectAdded() 和aboutToRemoveObject()两个信号关联到了相应的槽函数objectAdded(QObject*)和aboutToRemoveObject(QObject*)。当有对象添加到对象池当中时,就使用Aggregation来查询是不是StatusBarWidget类型,若是是该类型,就将相对应的Widget添加到状态栏的相应位置当中,并添加到窗口列表(QMap<QWidget *, IContext *> m_contextWidgets)当中。aboutToRemoveObject就是从窗口列表中删除。
与StatusBarManager同样,仅将对象池的objectAdded() 和aboutToRemoveObject()两个信号关联到了相应的槽函数objectAdded(QObject*)和aboutToRemoveObject(QObject*)。他查询的是IMode类型,若是是IMode类型,就将其添加到FancyTabWidget当中,并连接相应的槽,注册快捷键。
建立了一个Widget,这个Widget由OutputPaneManager来负责填充,并设置这个widget放在状态栏的第2个位置上(有4个位置),添加这个StatusBarWidget到对象池,相应的槽函数完成真正的插入工做。
该函数中建立MessageOutputWindow,并将其添加到对象池中。
简要代码以下:
void MainWindow::extensionsInitialized() { ....... m_statusBarManager->extensionsInitalized(); OutputPaneManager::instance()->init(); ....... // reading the shortcut settings must be done after all shortcuts have been registered m_actionManager->d->initialize(); ....... }
该函数为空,能够进行扩展。
首先在主窗口的menuBar中添加菜单,关联”清空“,”最大化/最小化“操做。而后从对象池当中获得全部的IOutputPane,并将它们根据在状态栏中的位置进行排序。而后将每一个IOutputPane的输出窗口outputWidget添加到QStackedWidget当中,将toolBarWidget添加到输出窗口上边的工具栏m_opToolBarWidgets(也是一个StackedWidget)中。
好,先写这么多,之后继续补充。