Qt例子学习笔记 - Examples/Qt-6.2.0/assistant/simpletextviewer

main.cpp

#include "mainwindow.h"

#include 
//QApplication 专门为 QGuiApplication 提供了一些基于 QWidget 的应用程序所需的功能。
// 它处理特定于小部件的初始化、完成。
//对于任何使用 Qt 的 GUI 应用程序,无论应用程序在任何给定时间是否有 0、1、2 或更多窗口,
//都恰好有一个 QApplication 对象。
//对于非基于 QWidget 的 Qt 应用程序,请改用 QGuiApplication,因为它不依赖于 QtWidgets 库。
//一些 GUI 应用程序提供了一种特殊的批处理模式,即。
//提供命令行参数,无需人工干预即可执行任务。
//在这种非 GUI 模式下,实例化一个普通的 QCoreApplication 通常就足够了,
//以避免不必要地初始化图形用户界面所需的资源。
//以下示例显示了如何动态创建适当类型的应用程序实例:
/*
QCoreApplication* createApplication(int &argc,char *argv[])
{
    for(int i = 1;i < argc; ++i)
    {
        if(!qstrcmp(argv[i],"-no-gui"))
            return new QCoreApplication(argc,argv);
    }
    return new QApplication(argc,argv);
}

int main(int argc,char *argv[])
{
    QScopedPointer app(createApplication(argc,argv));

    if(qobject_cast(app.data()))
    {
        //start GUI version
    }
    else
    {
        //start non-GUI version
    }
    return app->exec();
}
*/
//QApplication 对象可通过 instance() 函数访问,该函数返回等效于全局 qApp 指针的指针。
//QApplication 的主要职责范围是:
//它使用用户的桌面设置初始化应用程序,例如palette()、font() 和doubleClickInterval()。
//它会跟踪这些属性,以防用户全局更改桌面,例如通过某种控制面板。
//它执行事件处理,这意味着它从底层窗口系统接收事件并将它们分派给相关的小部件。
//通过使用 sendEvent() 和 postEvent(),您可以将自己的事件发送到小部件。
//它解析常见的命令行参数并相应地设置其内部状态。 有关更多详细信息,请参阅下面的构造函数文档。
//它定义了应用程序的外观和感觉,它被封装在一个 QStyle 对象中。
//这可以在运行时使用 setStyle() 进行更改。
//它通过 translate() 提供对用户可见的字符串的本地化。
//它提供了一些神奇的对象,比如 clipboard()。
//它知道应用程序的窗口。您可以使用 widgetAt() 询问哪个小部件位于某个位置,
//获取 topLevelWidgets() 和 closeAllWindows() 等列表。
//它管理应用程序的鼠标光标处理,参见 setOverrideCursor()
//由于 QApplication 对象进行了如此多的初始化,因此必须在创建与用户界面相关的任何其他对象之前创建它。
//QApplication 还处理常见的命令行参数。
//因此,在应用程序本身对 argv 进行任何解释或修改之前创建它通常是一个好主意。
//Groups of functions
//系统设置
/*
desktopSettingsAware(), 
setDesktopSettingsAware(), 
cursorFlashTime(), 
setCursorFlashTime(), 
doubleClickInterval(), 
setDoubleClickInterval(), 
setKeyboardInputInterval(), 
wheelScrollLines(), 
setWheelScrollLines(), 
palette(), setPalette(), 
font(), setFont(), fontMetrics().
*/
//事件处理
/*
exec(), 
processEvents(), 
exit(), 
quit(). 
sendEvent(), 
postEvent(), 
sendPostedEvents(), 
removePostedEvents(), notify().
*/

//GUI styles
/*
style(), setStyle().
*/

//文本处理
/*
installTranslator(), removeTranslator() translate().
*/
//Widgets

/*
allWidgets(), 
topLevelWidgets(), 
activePopupWidget(), 
activeModalWidget(), 
clipboard(), 
focusWidget(), 
activeWindow(), 
widgetAt().
*/

//Advanced cursor handling
/*
overrideCursor(), setOverrideCursor(), restoreOverrideCursor().
*/

//这个例子展示了如何在自定义应用程序中使用 Qt Assistant 作为自定义帮助查看器。
//这是分两个阶段完成的。
//首先创建文档,定制Qt助手;
//其次,在应用程序中添加了启动和控制 Qt 助手的功能。
//该示例由四个类组成:
//Assistant 提供了启动 Qt Assistant 的功能。
//MainWindow 是主应用程序窗口。
//FindFileDialog 允许用户使用通配符匹配来搜索文件。
//TextEdit 提供了一个富文本浏览器,可确保 HTML 文档中引用的图像正确显示。
//注意:我们只会评论与主要问题相关的实现部分,即让 Qt Assistant 充当我们的 Simple Text Viewer 应用程序的自定义帮助查看器。
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow window;
    window.show();
    return app.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

//在应用程序中,可以通过菜单、工具栏按钮和键盘快捷键调用许多常用命令。
//由于用户希望每个命令都以相同的方式执行,而不管使用的用户界面如何,将每个命令表示为一个动作是很有用的。
//操作可以添加到菜单和工具栏,并自动保持同步。
//例如,在文字处理器中,如果用户按下粗体工具栏按钮,粗体菜单项将被自动选中。
//QAction 可能包含图标、菜单文本、快捷方式、状态文本、“这是什么?” 文本和工具提示。
//其中大部分可以在构造函数中设置。 它们也可以通过 
//setIcon()、setText()、setIconText()、setShortcut()、
//setStatusTip()、setWhatsThis() 和 setToolTip() 独立设置。 
//对于菜单项,可以使用 setFont() 设置单独的字体。

//我们建议将操作创建为使用它们的窗口的子项。在大多数情况下,操作将是应用程序主窗口的子项。

//小部件应用程序中的 QAction
//创建 QAction 后,应将其添加到相关菜单和工具栏,然后连接到将执行操作的槽。 例如:
/*
    const QIcon openIcon = QIcon::fromTheme("document-open",QIcon(":/images/open.png"))
    QAction *openAct = new QAction(openIcon,tr("&Open..."),this);
    openAct->setShortcuts(QKeySequence::Open);
    openAct->setStatusTip(tr("Open an existing file"));
    connect(openAct,&QAction::triggered,this,&MainWindow::open);
    fileMenu->addAction(openAct);
    fileToolBar->addAction(openAct);
*/
//使用 QWidget::addAction() 或 QGraphicsWidget::addAction() 将Action添加到小部件。
//。 请注意,操作必须先添加到小部件才能使用。
//当快捷方式应该是全局的(即 Qt::ApplicationShortcut 作为 Qt::ShortcutContext)时,这也是正确的。
//动作可以创建为独立的对象。
//但它们也可能是在构建菜单期间创建的。
//QMenu 类包含用于创建适合用作菜单项的操作的函数。

//菜单小部件是一个选择菜单。
//它可以是菜单栏中的下拉菜单,也可以是独立的上下文菜单。
//当用户单击相应的项目或按下指定的快捷键时,菜单栏会显示下拉菜单。
//使用 QMenuBar::addMenu() 将菜单插入菜单栏中
//上下文菜单通常由一些特殊的键盘键或右键单击来调用。
//它们可以与 popup() 异步执行,也可以与 exec() 同步执行。
//菜单也可以响应按钮按下而被调用; 这些就像上下文菜单,只是它们的调用方式不同。

//Actions
//菜单由一系列操作项组成。使用 addAction()、addActions() 和 insertAction() 函数添加动作。
//一个动作垂直表示并由 QStyle 呈现。
//此外,动作可以有一个文本标签,一个在最左侧绘制的可选图标,以及诸如“Ctrl+X”之类的快捷键序列。
//可以使用 actions() 找到菜单所包含的现有操作。
//有四种操作项:分隔符、显示子菜单的操作、小部件和执行操作的操作。
//分隔符使用 addSeparator() 插入,子菜单使用 addMenu() 插入,所有其他项都被视为操作项。
//插入操作项时,您通常指定接收器和插槽。
//每当项目被触发()时,接收者都会收到通知。
//此外,QMenu 提供了两个信号,triggered() 和 hovered(),它们表示从菜单触发的 QAction。
//您可以使用 clear() 清除菜单并使用 removeAction() 删除单个操作项。
//QMenu 还可以提供 tear-off 菜单。  tear-off 菜单是包含菜单副本的顶级窗口。
//这使得用户可以“tear off”经常使用的菜单并将它们放置在屏幕上方便的位置。
//如果您想要特定菜单的此功能,请使用 setTearOffEnabled() 插入tear-off的句柄。
//可以使用 QWidgetAction 类将小部件插入菜单中。
//此类的实例用于保存小部件,并通过采用 QAction 的 addAction() 重载插入菜单。
//如果 QWidgetAction 触发了 trigger() 信号,菜单将关闭。


QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
QT_END_NAMESPACE

class Assistant;
class TextEdit;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

private slots:
    void about();
    void showDocumentation();
    void open();

protected:
    void closeEvent(QCloseEvent *event) override;

private:
    void createActions();
    void createMenus();

    Assistant *assistant;
    TextEdit *textViewer;

    QMenu *fileMenu;
    QMenu *helpMenu;

    QAction *assistantAct;
    QAction *clearAct;
    QAction *openAct;
    QAction *exitAct;
    QAction *aboutAct;
    QAction *aboutQtAct;
};

#endif

mainwindow.cpp

#include "assistant.h"
#include "findfiledialog.h"
#include "mainwindow.h"
#include "textedit.h"

#include 
#include 
#include 
#include 
#include 
#include 

//MainWindow 类为应用程序主窗口提供两个菜单:
//文件菜单让用户打开和查看现有文件,
//而帮助菜单提供有关应用程序和 Qt 的信息,
//并让用户打开 Qt 助手以显示应用程序的文档 .
//为了能够访问帮助功能,我们在 MainWindow 的构造函数中初始化 Assistant 对象。
MainWindow::MainWindow()
{
    assistant = new Assistant;
// ![0]
    textViewer = new TextEdit;
    //[static, since 6.0] QString QLibraryInfo::path(QLibraryInfo::LibraryPath p)
    //返回由 p 指定的路径。    
    //QLibraryInfo::ExamplesPath 安装时示例的路径。
    //QLatin1String 许多 QString 的成员函数被重载以接受 const char * 而不是 QString。
    //这包括复制构造函数、赋值运算符、比较运算符以及各种其他函数,
    //例如 insert()、replace() 和 indexOf()。
    //这些函数通常经过优化,以避免为 const char * 数据构造 QString 对象。
    //例如,假设 str 是一个 QString,
    /*
        if(str == "auto" || str == "extern"
            ||str == "static"||str == "register")
            {
                ...
            }
            //is much faster than
        if(str == QString("auto") || str == QString("extern")
            ||str == QString("static") || str == QString("register"))
        {
    
        }
    */
    //因为它没有构造四个临时 QString 对象并对字符数据进行深拷贝。
    //定义 QT_NO_CAST_FROM_ASCII 的应用程序(如 QString 文档中所述)无权访问 QString 的 const char * API。
    //为了提供一种指定常量 Latin-1 字符串的有效方法,
    //Qt 提供了 QLatin1String,它只是一个非常薄的 const char * 包装器。
    //使用QLatin1String,上面的示例代码变成
    /*
        if(str == QLatin1String("auto")
            ||str ==  QLatin1String("extern")
            ||str ==  QLatin1String("static")
            ||str ==  QLatin1String("register"))
        {}
    */
    //这输入的时间有点长,但它提供了与代码的第一个版本完全相同的好处,
    //并且比使用 QString::fromLatin1() 转换 Latin-1 字符串更快。
    //多亏了 QString(QLatin1String) 构造函数,
    //QLatin1String 可以在任何需要 QString 的地方使用。 例如:
    //QLabel *label = new QLabel(QLatin1String("MOD"),this);
    //注意:如果您使用 QLatin1String 参数调用的函数实际上并未重载以采用 QLatin1String
    //则隐式转换为 QString 将触发内存分配,这通常是您首先要使用 QLatin1String 避免的情况。
    //在这些情况下,使用 QStringLiteral 可能是更好的选择。


    textViewer->setContents(QLibraryInfo::path(QLibraryInfo::ExamplesPath)
            + QLatin1String("/assistant/simpletextviewer/documentation/intro.html"));
    //void QMainWindow::setCentralWidget(QWidget *widget)
    //将给定的小部件设置为主窗口的中央小部件。
    //注意: QMainWindow 获得小部件指针的所有权并在适当的时候将其删除。
    setCentralWidget(textViewer);

    createActions();
    createMenus();
    //此属性保存窗口标题(标题)
    //此属性仅对顶级小部件有意义,例如窗口和对话框。
    //如果未设置标题,则标题基于 windowFilePath。
    //如果这些都没有设置,则标题是一个空字符串。
    setWindowTitle(tr("Simple Text Viewer"));
    resize(750, 400);
// ![1]
}
//! [1]

//最后,我们必须重新实现受保护的 QWidget::closeEvent() 事件处理程序,
//以确保在终止应用程序之前正确关闭应用程序的 Qt Assistant 实例。
void MainWindow::closeEvent(QCloseEvent *)
{
    delete assistant;
}

void MainWindow::about()
{
    QMessageBox::about(this, tr("About Simple Text Viewer"),
                       tr("This example demonstrates how to use\n"
                          "Qt Assistant as help system for your\n"
                          "own application."));
}

//在 showDocumentation() 槽中,我们使用文档主页的 
//URL 调用 Assistant 类的 showDocumentation() 函数。
void MainWindow::showDocumentation()
{
    assistant->showDocumentation("index.html");
}

void MainWindow::open()
{
    FindFileDialog dialog(textViewer, assistant);
    dialog.exec();
}

//然后我们为 Simple Text Viewer 应用程序创建所有操作。
//特别感兴趣的是可以通过 F1 快捷方式或帮助 > 帮助目录菜单项访问的assistantAct 操作。
//此操作连接到 MainWindow 类的 showDocumentation() 槽。
void MainWindow::createActions()
{
    assistantAct = new QAction(tr("Help Contents"), this);
    assistantAct->setShortcut(QKeySequence::HelpContents);
    connect(assistantAct, &QAction::triggered, this, &MainWindow::showDocumentation);

    openAct = new QAction(tr("&Open..."), this);
    openAct->setShortcut(QKeySequence::Open);
    connect(openAct, &QAction::triggered, this, &MainWindow::open);

    clearAct = new QAction(tr("&Clear"), this);
    clearAct->setShortcut(tr("Ctrl+C"));
    connect(clearAct, &QAction::triggered, textViewer, &QTextEdit::clear);

    exitAct = new QAction(tr("E&xit"), this);
    exitAct->setShortcuts(QKeySequence::Quit);
    connect(exitAct, &QAction::triggered, this, &QWidget::close);

    aboutAct = new QAction(tr("&About"), this);
    connect(aboutAct, &QAction::triggered, this, &MainWindow::about);

    aboutQtAct = new QAction(tr("About &Qt"), this);
    connect(aboutQtAct, &QAction::triggered, QApplication::aboutQt);
//! [5]
}
//! [5]

void MainWindow::createMenus()
{
    fileMenu = new QMenu(tr("&File"), this);
    fileMenu->addAction(openAct);
    fileMenu->addAction(clearAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);

    helpMenu = new QMenu(tr("&Help"), this);
    helpMenu->addAction(assistantAct);
    helpMenu->addSeparator();
    helpMenu->addAction(aboutAct);
    helpMenu->addAction(aboutQtAct);


    menuBar()->addMenu(fileMenu);
    menuBar()->addMenu(helpMenu);
}

textedit.h

#ifndef TEXTEDIT_H
#define TEXTEDIT_H

#include 
#include 

class TextEdit : public QTextEdit
{
    Q_OBJECT

public:
    TextEdit(QWidget *parent = nullptr);
    void setContents(const QString &fileName);

private:
    //QVariant 由于 C++ 禁止联合包含具有非默认构造函数或析构函数的类型,
    //因此大多数有趣的 Qt 类不能在unions中使用。
    //如果没有 QVariant,这对于 QObject::property() 和数据库工作等来说将是一个问题。
    //QVariant 对象一次保存一个 typeId() 的单个值。 
    //(某些类型是多值的,例如字符串列表。)
    //您可以找出变体包含的类型 T,
    //使用 convert() 将其转换为其他类型,
    //使用 toT() 函数之一获取其值 (例如,toSize()),
    //并检查是否可以使用 canConvert() 将类型转换为特定类型。
    //名为 toT() 的方法(例如,toInt()、toString())是常量。
    //如果您要求存储类型,它们将返回存储对象的副本。
    //如果您要求可以从存储的类型生成的类型, toT() 会复制并转换对象本身并保持不变。
    //如果您要求的类型无法从存储的类型中生成,则结果取决于类型; 有关详细信息,请参阅函数文档。
    //下面是一些示例代码来演示 QVariant 的使用:
    /*
        QDataStream out(...);
        QVariant v(123);  变体现在包含一个 int
        int x = v.toInt(); //x = 123
        out<> v;  读取一个 Int 变量
        int z = v.toInt(); //z = 123
        qDebug("Type is %s",v.typeName());
        v = v.toInt() + 100; //The Variant now holds the value 223
        v = QVariant(QStringList()); //The variant now holds a QStrringList
    */
    //您甚至可以将 QList 和 QMap 值存储在一个变体中,
    //,因此您可以轻松构建任意类型的任意复杂的数据结构。
    //这是非常强大和通用的,但可能比在标准数据结构中存储特定类型的内存和速度效率低。
    //QVariant 还支持空值的概念。
    //如果变体不包含初始化值或包含空指针,则变体为空。
    /*
        QVariant x; // x.isNull() == true
        QVariant y = QVariant::fromValue(nullptr); // y.isNull() == true
       //QVariant 可以扩展以支持 QMetaType::Type 枚举中提到的类型之外的其他类型。 有关详细信息,请参阅创建自定义 Qt 类型。 
    */
    //关于 GUI 类型的说明
    //由于 QVariant 是 Qt Core 模块的一部分,
    //因此无法提供 Qt GUI 中定义的数据类型的转换功能,
    //例如 QColor、QImage 和 QPixmap。
    //换句话说,没有 toColor() 函数。
    //相反,您可以使用 QVariant::value() 或 qvariant_cast() 模板函数。 例如:
    /*
        QVariant variant;
        QColor color = variant.value();
    */

    //对于 QVariant 支持的所有数据类型,包括 GUI 相关类型,逆转换(例如,从 QColor 到 QVariant)是自动的:
    /*
        QColor color = palette().backgroud().color();
        QVariant variant = color;
    */

    QVariant loadResource(int type, const QUrl &name) override;
    QUrl srcUrl;
};

#endif

textedit.cpp

#include "textedit.h"

#include 
#include 
//QTextEdit 是一个先进的 WYSIWYG 查看器/编辑器,支持使用 HTML 样式标签或 
//Markdown 格式的富文本格式。 它经过优化,可处理大型文档并快速响应用户输入。
//QTextEdit 适用于段落和字符。
//一个段落是一个格式化的字符串,它被自动换行以适应小部件的宽度。
//默认情况下,阅读纯文本时,换行符表示一个段落。
//一个文档由零个或多个段落组成。 段落中的单词按照段落的对齐方式对齐。
//段落由硬换行符分隔。 段落中的每个字符都有自己的属性,例如字体和颜色。


//QTextEdit 可以显示图像、列表和表格。
//如果文本太大而无法在文本编辑的视口中查看,则会出现滚动条。
//文本编辑可以加载纯文本和富文本文件。
//可以使用 HTML 4 标记的子集来描述富文本; 有关更多信息,请参阅支持的 HTML 子集页面。
//如果您只需要显示一小段富文本,请使用 QLabel。
//Qt 中的富文本支持旨在提供一种快速、可移植和
//高效的方式来向应用程序添加合理的在线帮助工具,并为富文本编辑器提供基础。
//如果您发现 HTML 支持不足以满足您的需求,
//您可以考虑使用 Qt WebKit,它提供了一个全功能的 Web 浏览器小部件。
//QTextEdit 上鼠标光标的形状默认为 Qt::IBeamCursor。
//它可以通过 viewport() 的 cursor 属性进行更改。
//使用 QTextEdit 作为显示小部件
//QTextEdit 可以显示一个大的 HTML 子集,包括表格和图像。
//可以使用 setHtml() 设置或替换文本,它会删除任何现有文本并将其替换为在 setHtml() 调用中传递的文本。
//如果您使用旧版 HTML 调用 setHtml(),然后调用 toHtml(),则返回的文本可能具有不同的标记,但会呈现相同的内容。
//可以使用 clear() 删除整个文本。
//也可以使用 setMarkdown() 设置或替换文本,同样的警告也适用:
//如果您随后调用 toMarkdown(),返回的文本可能会有所不同,
//但会尽可能保留其含义。
//可以解析带有一些嵌入 HTML 的 Markdown,具有与 setHtml() 相同的限制;
//但是 toMarkdown() 只写“纯”的 Markdown,没有任何嵌入的 HTML。
//可以使用 QTextCursor 类或使用便利函数 insertHtml()、
//insertPlainText()、append() 或 paste() 插入文本本身。
//QTextCursor 还能够将复杂的对象(如表格或列表)插入到文档中
//并处理创建选择并将更改应用于所选文本。
//默认情况下,文本编辑在空格处包装单词以适合文本编辑小部件。
//setLineWrapMode() 函数用于指定您想要的换行类型,如果您不想要任何换行,则使用 NoWrap。
//调用 setLineWrapMode() 以设置固定像素宽度 FixedPixelWidth 或字符列(例如 80 列)
//FixedColumnWidth 与 setLineWrapColumnOrWidth() 指定的像素或列。
//如果您对小部件的宽度 WidgetWidth 使用自动换行
//您可以使用 setWordWrapMode() 指定是在空白处还是在任何地方换行。
//find() 函数可用于在文本中查找和选择给定的字符串。
//如果您想限制 QTextEdit 中的段落总数
//例如它在日志查看器中通常很有用
//那么您可以使用 QTextDocument 的 maximumBlockCount 属性。
//只读键绑定
//当 QTextEdit 以只读方式使用时,键绑定仅限于导航,并且只能使用鼠标选择文本:
// UpMoves 向上移动一行。
// DownMoves 向下移动一行。
// Left 向左移动一个字符。
// Right 向右移动一个字符。
// PageUp 向上移动一页(视口)。
// PageDown 向下移动一页(视口)。
// Home移动到文本的开头。
// EndMoves 到文本的结尾。
// Alt+Wheel 水平滚动页面(Wheel 是鼠标滚轮)。
// Ctrl+滚轮缩放文本。
// Ctrl+A 选择所有文本。
//文本编辑可能能够提供一些元信息。 
//例如,documentTitle() 函数将返回 HTML  标签内的文本。</span>
<span class="token comment">//注意:只有当 font-size 未设置为固定大小时,才能放大 HTML 文档。</span>
<span class="token comment">//使用 QTextEdit 作为编辑器</span>
<span class="token comment">//所有关于使用 QTextEdit 作为显示小部件的信息也适用于此。</span>
<span class="token comment">//当前字符格式的属性使用 setFontItalic()、setFontWeight()、</span>
<span class="token comment">//setFontUnderline()、setFontFamily()、setFontPointSize()、</span>
<span class="token comment">//setTextColor() 和 setCurrentFont() 设置。 </span>
<span class="token comment">//当前段落的对齐方式是使用 setAlignment() 设置的。</span>
<span class="token comment">//文本选择由 QTextCursor 类处理,该类提供创建选择、检索文本内容或删除选择的功能。</span>
<span class="token comment">//您可以使用 textCursor() 方法检索与用户可见光标对应的对象。</span>
<span class="token comment">//如果您想在 QTextEdit 中设置一个选择,</span>
<span class="token comment">//只需在 QTextCursor 对象上创建一个选择</span>
<span class="token comment">//然后使用 setTextCursor() 使该光标成为可见光标</span>
<span class="token comment">//可以使用 copy() 将选择复制到剪贴板,或使用 cut() 剪切到剪贴板。</span>
<span class="token comment">//可以使用 selectAll() 选择整个文本。</span>
<span class="token comment">//当光标移动并且基础格式属性更改时</span>
<span class="token comment">//发出 currentCharFormatChanged() 信号以反映新光标位置处的新属性。</span>
<span class="token comment">//只要文本发生变化(作为 setText() 的结果或通过编辑器本身),就会发出 textChanged() 信号。</span>
<span class="token comment">//QTextEdit 持有一个 QTextDocument 对象,</span>
<span class="token comment">//可以使用 document() 方法检索该对象。</span>
<span class="token comment">//您还可以使用 setDocument() 设置您自己的文档对象。</span>
<span class="token comment">//QTextDocument 提供了一个 isModified() 函数</span>
<span class="token comment">//如果文本自加载后或自上次调用 setModified 以来已被修改,</span>
<span class="token comment">//则该函数将返回 true,并将 false 作为参数。</span>
<span class="token comment">//此外,它还提供了撤销和重做的方法。</span>

<span class="token comment">//Drag and Drop</span>
<span class="token comment">//QTextEdit 还支持自定义拖放行为。</span>
<span class="token comment">//默认情况下,当用户将这些 MIME 类型的数据放到文档中时</span>
<span class="token comment">//QTextEdit 将插入纯文本、HTML 和富文本。</span>
<span class="token comment">//重新实现 canInsertFromMimeData() 和 insertFromMimeData() 以添加对其他 MIME 类型的支持。</span>
<span class="token comment">//例如,要允许用户将图像拖放到 QTextEdit 上,您可以通过以下方式实现这些功能:</span>
<span class="token comment">/*
    bool TextEdit::canInsertFromMimeData(const QMimeData *source) const
    {
        if(source->hasImage())
            return true;
        else
            return QTextEdit::canInsertFromMimeData(source);
    }
*/</span>
<span class="token comment">//我们通过返回 true 来添加对图像 MIME 类型的支持。</span>
<span class="token comment">//对于所有其他 MIME 类型,我们使用默认实现。</span>
<span class="token comment">/*
void TextEdit::insertFromMimeData(const QMimeData *source)
{
    if(source->hasImage())
    {
        QImage image = qvariant_cast<QImage>(source->imageData());
        QTextCursor cursor = this->textCursor();
        QTextDocument *document =  this->document();
        document->addResource(QTextDocument::ImageResource,QUrl("image"),image);
        cursor.insertImage("image");
    }
}
*/</span>
<span class="token comment">//我们从 MIME 源保存的 QVariant 中解压图像并将其作为资源插入到文档中。</span>


<span class="token class-name">TextEdit</span><span class="token operator">::</span><span class="token function">TextEdit</span><span class="token punctuation">(</span>QWidget <span class="token operator">*</span>parent<span class="token punctuation">)</span>
    <span class="token operator">:</span> <span class="token function">QTextEdit</span><span class="token punctuation">(</span>parent<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//此属性保存文本编辑是否为只读</span>
    <span class="token comment">//在只读文本编辑中,用户只能浏览文本和选择文本; 修改文本是不可能的</span>
    <span class="token function">setReadOnly</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">TextEdit</span><span class="token operator">::</span><span class="token function">setContents</span><span class="token punctuation">(</span><span class="token keyword">const</span> QString <span class="token operator">&</span>fileName<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//QFileInfo 提供有关文件系统中文件的名称和位置(路径)</span>
    <span class="token comment">//访问权限以及它是目录还是符号链接等信息。</span>
    <span class="token comment">//文件的大小和上次修改/读取时间也可用</span>
    <span class="token comment">//QFileInfo 还可用于获取有关 Qt 资源的信息。</span>
    <span class="token comment">//QFileInfo 可以指向具有相对或绝对文件路径的文件。</span>
    <span class="token comment">//绝对文件路径以目录分隔符“/”(或 Windows 上的驱动器规范)开头。</span>
    <span class="token comment">//相对文件名以目录名或文件名开头,并指定相对于当前工作目录的路径。</span>
    <span class="token comment">//绝对路径的一个例子是字符串“/tmp/quartz”。</span>
    <span class="token comment">//相对路径可能看起来像“src/fatlib”。</span>
    <span class="token comment">//。 您可以使用函数 isRelative() 来检查 QFileInfo 使用的是相对文件路径还是绝对文件路径。</span>
    <span class="token comment">//您可以调用函数 makeAbsolute() 将相对 QFileInfo 的路径转换为绝对路径。</span>
    <span class="token comment">//注意:以冒号 (:) 开头的路径始终被视为绝对路径,因为它们表示 QResource。</span>
    <span class="token comment">//QFileInfo 处理的文件在构造函数中设置或稍后使用 setFile() 设置。</span>
    <span class="token comment">//使用exists() 查看文件是否存在,使用size() 获取其大小。</span>
    <span class="token comment">//文件的类型通过 isFile()、isDir() 和 isSymLink() 获得。</span>
    <span class="token comment">//symLinkTarget() 函数提供符号链接指向的文件的名称。</span>
    <span class="token comment">//在 Unix(包括 macOS 和 iOS)上,</span>
    <span class="token comment">//此类中的属性 getter 函数返回目标文件的时间和大小等属性</span>
    <span class="token comment">//,而不是符号链接,因为 Unix 透明地处理符号链接。</span>
    <span class="token comment">//使用 QFile 打开符号链接可以有效地打开链接的目标。 例如:</span>
    <span class="token comment">/*
        #ifdef Q_OS_UNIX
        QFileInfo info1("/home/bob/bin/untabify")
        info1.isSymLink(); //returns true
        info1.absoluteFilePath(); //return "/home/bob/bin/untabify"
        info1.size();   //return 56201
        info1.symLinkTarget(); //return "/opt/pretty++/bin/untabify"

        QFileInfo info2(info1.symLinkTarget());
        info2.isSymLink(); //return false
        info2.absoluteFilePath(); //returns "/opt/pretty++/bin/untabify"
        info2.size(); //return 56201

        #endif
    */</span>
    <span class="token comment">//在 Windows 上,快捷方式(.lnk 文件)当前被视为符号链接。</span>
    <span class="token comment">//在 Unix 系统上,属性 getter 返回目标文件的大小,而不是 .lnk 文件本身。</span>
    <span class="token comment">//此行为已被弃用,并且可能会在 Qt 的未来版本中删除,之后 .lnk 文件将被视为常规文件。</span>
    <span class="token comment">/*
        #ifdef Q_OS_WIN
        QFileInfo info1("C:\\Documents and Settings\\Bob\\untabify.lnk");
        info1.isSymLink(); //return true;
        info1.absoluteFilePath(); //returns "C:/Documents and Settings/Bob/untabify.lnk"
        info1.size(); // returns 743
        info1.symLinkTarget(); //returns "C:/Pretty++/untabify"

        QFileInfo info2(info1.symLinkTarget());
        info2.isSymLink(); //return false
        info2.absoluteFilePath(); //return "C:/Pretty++/untabify"
        info2.size(); //return 63942
        #endif
    */</span>
    <span class="token comment">//可以使用 path() 和 fileName() 提取文件名的元素。</span>
    <span class="token comment">//可以使用 baseName()、suffix() 或 completeSuffix() 提取 fileName() 的部分。</span>
    <span class="token comment">//由 Qt 类创建的目录的 QFileInfo 对象将没有尾随文件分隔符。</span>
    <span class="token comment">//如果您希望在您自己的文件信息对象中使用尾随分隔符,只需在给定构造函数或 setFile() 的文件名后附加一个。</span>
    <span class="token comment">//文件的日期由birthTime()、lastModified()、lastRead() 和fileTime() 返回。</span>
    <span class="token comment">//有关文件访问权限的信息是通过 isReadable()、isWritable() 和 isExecutable() 获得的。</span>
    <span class="token comment">//文件的所有权可从 owner()、ownerId()、group() 和 groupId() 获得。</span>
    <span class="token comment">//您可以使用 permission() 函数在单个语句中检查文件的权限和所有权。</span>
    <span class="token comment">//注意:在 NTFS 文件系统上,出于性能原因,默认情况下禁用所有权和权限检查。</span>
    <span class="token comment">//要启用它,请包含以下行:</span>
    <span class="token comment">//extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;</span>
    <span class="token comment">//然后通过将 qt_ntfs_permission_lookup 递增和递减 1 来打开和关闭权限检查。</span>
    <span class="token comment">/*
        qt_ntfs_permission_lookup++;//turn checking on
        qt_ntfs_permission_lookup--;//turn if off again        
    */</span>
    <span class="token comment">//性能问题</span>
    <span class="token comment">//QFileInfo 的一些函数查询文件系统,但出于性能原因,一些函数只对文件名本身进行操作。</span>
    <span class="token comment">//例如:要返回相对文件名的绝对路径,absolutePath() 必须查询文件系统。</span>
    <span class="token comment">//然而,path() 函数可以直接处理文件名,因此速度更快。</span>
    <span class="token comment">//注意:为了提高性能,QFileInfo 缓存有关文件的信息。</span>
    <span class="token comment">//因为文件可以被其他用户或程序,甚至同一程序的其他部分更改,</span>
    <span class="token comment">//所以有一个函数可以刷新文件信息:refresh()。</span>
    <span class="token comment">//如果您想关闭 QFileInfo 的缓存并强制它在每次从它请求信息时访问文件系统,</span>
    <span class="token comment">//请调用 setCaching(false)。 如果要确保从文件系统读取所有信息,请使用 stat()。</span>

    QFileInfo <span class="token function">fi</span><span class="token punctuation">(</span>fileName<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//absoluteFilePath返回包含文件名的绝对路径。</span>
    <span class="token comment">//绝对路径名由完整路径和文件名组成。</span>
    <span class="token comment">//在 Unix 上,这将始终以根目录“/”开头。</span>
    <span class="token comment">//在 Windows 上,这将始终以“D:/”开头,</span>
    <span class="token comment">//其中 D 是驱动器号,但未映射到驱动器号的网络共享除外,在这种情况下,路径将以“//sharename/”开头。</span>
    <span class="token comment">//QFileInfo 将大写驱动器号。 请注意, QDir 不会这样做。</span>
    <span class="token comment">//下面的代码片段显示了这一点。</span>
    <span class="token comment">/*
        QFileInfo fi("c:/temp/foo"); =>fi.absoluteFilePath=>"C:/temp/foo"
    */</span>
    <span class="token comment">//此函数返回与 filePath() 相同的值</span>
    <span class="token comment">//,除非 isRelative() 为真。</span>
    <span class="token comment">//与 canonicalFilePath() 相反</span>
    <span class="token comment">//符号链接或多余的“.” 或“..”元素不一定被删除。</span>

    <span class="token comment">//[static] QUrl QUrl::fromLocalFile(const QString &localFile)</span>
    <span class="token comment">//返回 localFile 的 QUrl 表示,解释为本地文件</span>
    <span class="token comment">//此函数接受由斜杠分隔的路径以及此平台的本机分隔符。</span>
    <span class="token comment">//此函数还接受带有双前导斜杠(或反斜杠)的路径来指示远程文件,</span>
    <span class="token comment">//如“//servername/path/to/file.txt”。</span>
    <span class="token comment">//请注意,实际上只有某些平台才能使用 QFile::open() 打开此文件。</span>
    <span class="token comment">//空的 localFile 会导致空的 URL(自 Qt 5.4 起)。</span>
    <span class="token comment">/*
        qDebug()<<QUrl::fromLocalFile("file.txt"); //QUrl("file:file.txt")
        qDebug()<<QUrl::fromLocalFile("/home/user/file.txt"); //Qurl("file:///home/user/file.txt")
        qDebug()<<QUrl::fromLocalFile("file:file.txt"); //doesn't make sense;expects path, not url with schem
    */</span>
    <span class="token comment">//在上面代码片段的第一行中,文件 URL 是根据本地相对路径构造的。</span>
    <span class="token comment">//具有相对路径的文件 URL 仅在存在可对其进行解析的基本 URL 时才有意义。 例如</span>
    <span class="token comment">/*
        QUrl url = QUrl::fromLocalFile("file.txt");
        QUrl baseUrl = QUrl("file:/home/user/");
        //wrong:prints QUrl("file:file.txt") as url already has a scheme
        qDebug()<<baseUrl.resolved(url);
    */</span> 
    <span class="token comment">//因此,最好对相对文件路径使用相对 URL(即无方案):</span>
    <span class="token comment">/*
        QUrl url = QUrl("file.txt")
        QUrl baseUrl = QUrl("file:/home/user/");
        //prints QUrl("file:///home/user/file.txt")
        qDebug()<<baseUrl.resolved(url);
    */</span>
    srcUrl <span class="token operator">=</span> <span class="token class-name">QUrl</span><span class="token operator">::</span><span class="token function">fromLocalFile</span><span class="token punctuation">(</span>fi<span class="token punctuation">.</span><span class="token function">absoluteFilePath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//QFile 是一种用于读写文本和二进制文件和资源的 I/O 设备。</span>
    <span class="token comment">//QFile 可以单独使用,或者更方便地与 QTextStream 或QDataStream 一起使用。</span>
    <span class="token comment">//文件名通常在构造函数中传递,但可以随时使用 setFileName() 设置。</span>
    <span class="token comment">//无论操作系统如何,QFile 都希望文件分隔符为“/”。 不支持使用其他分隔符(例如,“\”)。</span>
    <span class="token comment">//您可以使用exists() 检查文件是否存在,并使用remove() 删除文件。</span>
    <span class="token comment">//(更高级的文件系统相关操作由 QFileInfo 和 QDir 提供。)</span>
    <span class="token comment">//文件用open() 打开,用close() 关闭,用flush() 刷新。</span>
    <span class="token comment">//通常使用 QDataStream 或 QTextStream 读取和写入数据,</span>
    <span class="token comment">//但您也可以调用 QIODevice 继承的函数 read()、readLine()、readAll()、write()。</span>
    <span class="token comment">//QFile 还继承了 getChar()、putChar() 和 ungetChar(),它们一次处理一个字符。</span>
    <span class="token comment">//文件的大小由 size() 返回。</span>
    <span class="token comment">//您可以使用 pos() 获取当前文件位置,或使用 seek() 移动到新文件位置。</span>
    <span class="token comment">//如果您已到达文件末尾,则 atEnd() 返回 true。</span>
    
    <span class="token comment">//Reading Files Directly</span>
    <span class="token comment">//以下示例逐行读取文本文件:</span>
    <span class="token comment">/*
        QFile file("in.txt");
        if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
        while(!file.atEnd())
        {
            QByteArray line = file.readLine();
            process_line(line);
        }
    */</span>
    <span class="token comment">//传递给 open() 的 QIODevice::Text 标志告诉 Qt 将 Windows 样式的行终止符(“\r\n”)转换为 C++ 样式的终止符(“\n”)。</span>
    <span class="token comment">//默认情况下,QFile 假定为二进制,即它不对存储在文件中的字节执行任何转换。</span>

    <span class="token comment">//Using Streams to Read Files</span>
    <span class="token comment">//下一个示例使用 QTextStream 逐行读取文本文件:</span>
    <span class="token comment">/*
        QFile file("in.txt");
        if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
        QTextStream in(&file);  
        while(!in.atEnd())
        {
            QString line = in.readLine();
            process_line(line);
        }
    */</span>
    <span class="token comment">//QTextStream 负责将存储在磁盘上的 8 位数据转换为 16 位 Unicode QString。</span>
    <span class="token comment">//默认情况下,它假定文件以 UTF-8 编码。 这可以使用 QTextStream::setEncoding() 更改。</span>
    <span class="token comment">//要写文本,我们可以使用operator<<(),它被重载,左边是QTextStream,右边是各种数据类型(包括QString):</span>
    <span class="token comment">/*
        QFile file("out.txt");
        if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
            return;
        QTextStream out(&file);
        out<<"The magic number is: "<<49<<"\n";
    */</span>
    <span class="token comment">//QDataStream 与此类似,您可以使用 operator<<() 写入数据</span>
    <span class="token comment">//使用 operator>>() 读取数据。 有关详细信息,请参阅类文档。</span>
    <span class="token comment">//当您使用 QFile、QFileInfo 和 QDir 访问带有 Qt 的文件系统时,</span>
    <span class="token comment">//您可以使用 Unicode 文件名。</span>
    <span class="token comment">//在 Unix 上,这些文件名被转换为 8 位编码。</span>
    <span class="token comment">//如果您想使用标准 C++ API(<cstdio> 或 <iostream>)或特定于平台的 API 来访问文件而不是 QFile,</span>
    <span class="token comment">//您可以使用 encodeName() 和 decodeName() 函数在 Unicode 文件名和 8- 位文件名。</span>
    <span class="token comment">//在 Unix 上,有一些特殊的系统文件(例如在 /proc 中)</span>
    <span class="token comment">//它们的 size() 将始终返回 0,但您仍然可以从这样的文件中读取更多数据;</span>
    <span class="token comment">//数据是直接响应您调用 read() 生成的。</span>
    <span class="token comment">//但是,在这种情况下,您不能使用 atEnd() 来确定是否有更多数据要读取</span>
    <span class="token comment">//(因为 atEnd() 将为声称大小为 0 的文件返回 true)。</span>
    <span class="token comment">//相反,您应该调用 readAll(),或者重复调用 read() 或 readLine(),</span>
    <span class="token comment">//直到无法读取更多数据。 下一个示例使用 QTextStream 逐行读取/proc/modules:</span>
    <span class="token comment">/*
        QFile file("/proc/modules");
        if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
        QTextStream in(&file);
        QString line = in.readLine();
        while(!line.isNull())
        {
            process_line(line);
            line = in.readline();
        }
    */</span>
    <span class="token comment">//Signals</span>
    <span class="token comment">//与其他 QIODevice 实现(例如 QTcpSocket)不同,</span>
    <span class="token comment">//QFile 不会发出 aboutToClose()、bytesWritten() 或 readyRead() 信号。</span>
    <span class="token comment">//这个实现细节意味着 QFile 不适合读写某些类型的文件,比如 Unix 平台上的设备文件。</span>
    <span class="token comment">//平台特定问题</span>
    <span class="token comment">//文件权限在类 Unix 系统和 Windows 上的处理方式不同。</span>
    <span class="token comment">//在类 Unix 系统上的不可写目录中,无法创建文件。</span>
    <span class="token comment">//在 Windows 上情况并非总是如此,例如,“我的文档”目录通常不可写,但仍然可以在其中创建文件。</span>
    <span class="token comment">//Qt 对文件权限的理解是有限的</span>
    <span class="token comment">//这尤其影响 QFile::setPermissions() 函数。</span>
    <span class="token comment">//在 Windows 上,Qt 将只设置传统的只读标志,并且只有在没有任何 Write* 标志被传递时才会设置。</span>
    <span class="token comment">//Qt 不操作访问控制列表 (ACL),这使得该功能对于 NTFS 卷几乎没有用。</span>
    <span class="token comment">//它可能仍可用于使用 VFAT 文件系统的 U 盘。 POSIX ACL 也不会被操纵</span>

    QFile <span class="token function">file</span><span class="token punctuation">(</span>fileName<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//[override virtual] bool QFile::open(QIODeviceBase::OpenMode mode)</span>
    <span class="token comment">//重新实现:QIODevice::open(QIODeviceBase::OpenMode 模式)。</span>
    <span class="token comment">//使用OpenMode模式打开文件,成功则返回true; 否则为假。</span>
    <span class="token comment">//模式必须为 QIODevice::ReadOnly、QIODevice::WriteOnly 或 QIODevice::ReadWrite。</span>
    <span class="token comment">//可能还有其他标志,例如 QIODevice::Text 和 QIODevice::Unbuffered。</span>
    <span class="token comment">//注意:在WriteOnly 或ReadWrite 模式下,如果相关文件尚不存在,该函数将在打开之前尝试创建一个新文件。</span>
    <span class="token comment">//bool QFile::open(FILE *fh, QIODeviceBase::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)</span>
    <span class="token comment">//在给定的模式下打开现有的文件句柄 fh。</span>
    <span class="token comment">//handleFlags 可用于指定其他选项。 成功则返回真; 否则返回false</span>
    <span class="token comment">/*
        #include <stdio.h>

        void printError(const char* msg)
        {
            QFile file;
            file.open(stderr,QIODevice::WriteOnly);
            file.write(msg,qstrlen(msg)); //write to stderr
            file.close();
        }
    */</span>
    <span class="token comment">//当使用此函数打开 QFile 时,</span>
    <span class="token comment">//close() 的行为由 AutoCloseHandle 标志控制。</span>
    <span class="token comment">//如果指定了 AutoCloseHandle,并且此函数成功,</span>
    <span class="token comment">//则调用 close() 关闭采用的句柄。</span>
    <span class="token comment">//否则, close() 实际上不会关闭文件,而只会刷新它。</span>
    <span class="token comment">//Warning:</span>
    <span class="token comment">//如果 fh 不引用常规文件,例如,它是 stdin、stdout 或 stderr,则您可能无法使用 seek()。</span>
    <span class="token comment">//size() 在这些情况下返回 0。</span>
    <span class="token comment">//有关更多信息,请参阅 QIODevice::isSequential()。</span>
    <span class="token comment">//由于此函数在不指定文件名的情况下打开文件,因此您不能将此 QFile 与 QFileInfo 一起使用。</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>file<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span>QIODevice<span class="token operator">::</span>ReadOnly<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//QByteArray QIODevice::readAll()</span>
        <span class="token comment">//从设备读取所有剩余数据,并将其作为字节数组返回。</span>
        <span class="token comment">//这个功能没有报错的函数; 返回一个空的 QByteArray </span>
        <span class="token comment">//可能意味着当前没有数据可供读取,或者发生了错误。</span>
        QString <span class="token function">data</span><span class="token punctuation">(</span>file<span class="token punctuation">.</span><span class="token function">readAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//bool QString::endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const</span>
        <span class="token comment">//如果字符串以 s 结尾,则返回 true; 否则返回false。</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>fileName<span class="token punctuation">.</span><span class="token function">endsWith</span><span class="token punctuation">(</span><span class="token string">".html"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token comment">//void setHtml(const QString &text)</span>
            <span class="token comment">//此属性为文本编辑的文本提供了 HTML 界面</span>
            <span class="token comment">//toHtml() 将文本编辑的文本返回为 html。</span>
            <span class="token comment">//setHtml() 更改文本编辑的文本。任何先前的文本都将被删除,</span>
            <span class="token comment">//撤消/重做历史记录将被清除。 输入文本被解释为 html 格式的富</span>
            <span class="token comment">//文本。 currentCharFormat() 也被重置,除非 textCursor() 已经</span>
            <span class="token comment">//在文档的开头。</span>
            <span class="token comment">//注意:调用者有责任确保在创建包含 HTML 的 QString 并将其传</span>
            <span class="token comment">//递给 setHtml() 时正确解码文本。</span>
            <span class="token comment">//默认情况下,对于新创建的空文档,此属性包含用于描述没有正文文本的 HTML 4.0 文档的文本。            </span>
            <span class="token function">setHtml</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">else</span>
            <span class="token comment">//[slot] void QTextEdit::setPlainText(const QString &text)</span>
            <span class="token comment">//将文本编辑的文本更改为字符串文本。</span>
            <span class="token comment">//任何先前的文本都将被删除。</span>
            <span class="token comment">//Notes:</span>
            <span class="token comment">//text 被解释为纯文本。</span>
            <span class="token comment">//撤消/重做历史也被清除。</span>
            <span class="token comment">//currentCharFormat() 被重置,除非 textCursor() 已经在文档的开头。</span>
            <span class="token function">setPlainText</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

QVariant <span class="token class-name">TextEdit</span><span class="token operator">::</span><span class="token function">loadResource</span><span class="token punctuation">(</span><span class="token keyword">int</span> type<span class="token punctuation">,</span> <span class="token keyword">const</span> QUrl <span class="token operator">&</span>name<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//QTextDocument::ImageResource</span>
    <span class="token comment">//该资源包含图像数据。</span>
    <span class="token comment">//当前支持的数据类型是 QMetaType::QPixmap 和 QMetaType::QImage。</span>
    <span class="token comment">//如果相应的变体是 QMetaType::QByteArray 类型,则 Qt 尝试使用</span>
    <span class="token comment">//QImage::loadFromData 加载图像。</span>
    <span class="token comment">//当前不支持 QMetaType::QIcon。</span>
    <span class="token comment">//图标需要首先转换为支持的类型之一,例如使用 QIcon::pixmap。</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>type <span class="token operator">==</span> QTextDocument<span class="token operator">::</span>ImageResource<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//QString QUrl::toLocalFile() const</span>
        <span class="token comment">//返回格式化为本地文件路径的此 URL 的路径。</span>
        <span class="token comment">//返回的路径将使用正斜杠,即使它最初是用反斜杠创建的。</span>
        <span class="token comment">//如果此 URL 包含非空主机名,它将以 SMB 网络上的形式</span>
        <span class="token comment">//(例如,“//servername/path/to/file.txt”)在返回值中编码。</span>
        <span class="token comment">/*
            qDebug()<<QUrl("file:file.txt").toLocalFile(); //"file.txt"
            qDebug()<<QUrl("file:/home/user/file.txt").toLocalFile(); //"/home/user/file.txt"
            qDebug()<<QUrl("file.txt").toLocalFile();//"";wasn't a local file
        */</span>
        QFile <span class="token function">file</span><span class="token punctuation">(</span>srcUrl<span class="token punctuation">.</span><span class="token function">resolved</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLocalFile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>file<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span>QIODevice<span class="token operator">::</span>ReadOnly<span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token comment">//QByteArray QIODevice::readAll()</span>
            <span class="token comment">//从设备读取所有剩余数据,并将其作为字节数组返回</span>
            <span class="token comment">//这个功能没有报错的办法;</span>
            <span class="token comment">//返回一个空的 QByteArray 可能意味着当前没有数据可供读取,或者发生了错误。</span>
            <span class="token keyword">return</span> file<span class="token punctuation">.</span><span class="token function">readAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//[virtual invokable] QVariant QTextEdit::loadResource(int type, const QUrl &name)</span>
    <span class="token comment">//加载由给定类型和名称指定的资源。</span>
    <span class="token comment">//这个函数是 QTextDocument::loadResource() 的扩展。</span>
    <span class="token comment">//[virtual protected invokable] QVariant QTextDocument::loadResource(int type, const QUrl &name)</span>
    <span class="token comment">//从具有给定名称的资源加载指定类型的数据。</span>
    <span class="token comment">//该函数由富文本引擎调用,</span>
    <span class="token comment">//以请求未由 QTextDocument 直接存储但仍与其关联的数据。</span>
    <span class="token comment">//例如,图像被 QTextImageFormat 对象的 name 属性间接引用。</span>
    <span class="token comment">//当被 Qt 调用时,type 是QTextDocument::ResourceType 的值之一。</span>
    <span class="token comment">//如果 QTextDocument 是具有可调用 loadResource 方法</span>
    <span class="token comment">//(例如 QTextEdit、QTextBrowser 或 QTextDocument 本身)的 QObject 的子对象,则默认实现会尝试从父对象检索数据。</span>
    <span class="token keyword">return</span> <span class="token class-name">QTextEdit</span><span class="token operator">::</span><span class="token function">loadResource</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p>findfiledialog.h</p> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">FINDFILEDIALOG_H</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">FINDFILEDIALOG_H</span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QDialog></span></span>

QT_BEGIN_NAMESPACE
<span class="token comment">//QComboBox 提供了一种以占用最少屏幕空间的方式向用户呈现选项列表的方法。</span>
<span class="token comment">//组合框是一个显示当前项目的选择小部件,可以弹出一个可选择项目的列表。</span>
<span class="token comment">//组合框可以是可编辑的,允许用户修改列表中的每个项目。</span>
<span class="token comment">//组合框可以包含像素图和字符串;</span>
<span class="token comment">//insertItem() 和 setItemText() 函数被适当地重载。</span>
<span class="token comment">//对于可编辑的组合框,提供了函数 clearEditText() 以清除显示的字符串而不更改组合框的内容。</span>
<span class="token comment">//如果组合框的当前项目发生变化,则会发出三个信号:</span>
<span class="token comment">//currentIndexChanged()、currentTextChanged() 和 activate()。</span>
<span class="token comment">//currentIndexChanged() 和 currentTextChanged() 总是被发出,</span>
<span class="token comment">//无论更改是通过编程还是通过用户交互完成,</span>
<span class="token comment">//而 activate() 仅在更改由用户交互引起时发出。</span>
<span class="token comment">//当用户突出显示组合框弹出列表中的项目时,会发出 highlight() 信号。</span>
<span class="token comment">//所有三个信号都存在两种版本,一种带有 QString 参数,另一种带有 int 参数。</span>
<span class="token comment">//。 如果用户选择或突出显示像素图,则仅发出 int 信号。</span>
<span class="token comment">//每当可编辑组合框的文本发生更改时,就会发出 editTextChanged() 信号。</span>
<span class="token comment">//当用户在可编辑的组合框中输入新字符串时,小部件可能会也可能不会插入它,并且可以将它插入到多个位置。</span>
<span class="token comment">//默认策略是 InsertAtBottom,但您可以使用 setInsertPolicy() 更改此策略。</span>
<span class="token comment">//可以使用 QValidator 将输入限制为可编辑的组合框;</span>
<span class="token comment">//请参见 setValidator()。 默认情况下,接受任何输入。</span>
<span class="token comment">//例如,可以使用插入函数 insertItem() 和 insertItems() 填充组合框。</span>
<span class="token comment">//可以使用 setItemText() 更改项目。</span>
<span class="token comment">//可以使用 removeItem() 删除项目,可以使用 clear() 删除所有项目。</span>
<span class="token comment">//当前项的文本由 currentText() 返回,编号项的文本由 text() 返回。</span>
<span class="token comment">//当前项目可以使用 setCurrentIndex() 设置。</span>
<span class="token comment">//组合框中的项目数由 count() 返回;</span>
<span class="token comment">//可以使用 setMaxCount() 设置最大项目数。</span>
<span class="token comment">//您可以允许使用 setEditable() 进行编辑。</span>
<span class="token comment">//对于可编辑的组合框,您可以使用 setCompleter() 设置自动完成功能,并使用 setDuplicatesEnabled() 设置用户是否可以添加重复项。</span>
<span class="token comment">//QComboBox 为其弹出列表使用模型/视图框架并存储其项目。</span>
<span class="token comment">//默认情况下, QStandardItemModel 存储项目, QListView 子类显示弹出列表。</span>
<span class="token comment">//您可以直接访问模型和视图(使用 model() 和 view()),但 QComboBox 还提供设置和获取项目数据的功能(例如,setItemData() 和 itemText())。</span>
<span class="token comment">//您还可以设置新模型和视图(使用 setModel() 和 setView())。</span>
<span class="token comment">//对于组合框标签中的文本和图标,使用具有 Qt::DisplayRole 和 Qt::DecorationRole 的模型中的数据。</span>
<span class="token comment">//请注意,您不能更改 view() 的 SelectionMode,例如,通过使用 setSelectionMode()。</span>

<span class="token keyword">class</span> <span class="token class-name">QComboBox</span><span class="token punctuation">;</span>

<span class="token comment">//对话框和消息框通常以符合该平台界面指南的布局呈现按钮。</span>
<span class="token comment">//不同平台的对话框总是有不同的布局。</span>
<span class="token comment">//QDialogButtonBox 允许开发人员向其添加按钮,并将自动为用户的桌面环境使用适当的布局。</span>
<span class="token comment">//对话框的大多数按钮都遵循某些角色。 此类角色包括:</span>
<span class="token comment">//接受或拒绝对话。</span>
<span class="token comment">//寻求帮助。</span>
<span class="token comment">//对对话框本身执行操作(例如重置字段或应用更改)。</span>
<span class="token comment">//也可以有其他方式关闭对话框,这可能会导致破坏性结果。</span>
<span class="token comment">//大多数对话框都有几乎可以被视为标准的按钮</span>
<span class="token comment">//(例如确定和取消按钮)。 有时以标准方式创建这些按钮会很方便。</span>
<span class="token comment">//有几种使用 QDialogButtonBox 的方法。</span>
<span class="token comment">//一种方法是自己创建按钮(或按钮文本)并将它们添加到按钮框,指定它们的作用。</span>
<span class="token comment">/*
    findButton = new QPushButton(tr("&Find"));
    findButton->setDefault(true);

    moreButton = new QPushButton(tr("&More"));
    moreButton->setCheckable(true);
    moreButton->setAutoDefault(false);
*/</span>

<span class="token comment">//或者, QDialogButtonBox 提供了几个您可以使用的标准按钮</span>
<span class="token comment">//(例如确定、取消、保存)。 它们作为标志存在,因此您可以在</span>
<span class="token comment">//构造函数中将它们组合在一起。</span>

<span class="token comment">/*
    buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
                                |QDialogButtonBox::Cancel);
    connect(buttonBox,&QDialogButtonBox::accepted,this,&QDialog::accept);
    connect(buttonBox,&QDialogButtonBox::rejected,this,&QDialog::reject);
*/</span>
<span class="token comment">//您可以混合搭配普通按钮和标准按钮。</span>
<span class="token comment">//目前,如果按钮框是水平的,按钮的布局方式如下:</span>
<span class="token comment">//当在按钮框中单击按钮时,会为实际按下的按钮发出 clicked() 信号。</span>
<span class="token comment">//为方便起见,如果按钮具有 AcceptRole、RejectRole 或 </span>
<span class="token comment">//HelpRole,则分别发出 Accepted()、rejected() 或 helpRequested() 信号。</span>
<span class="token comment">//如果你想要一个特定的按钮是默认的,</span>
<span class="token comment">//你需要自己调用 QPushButton::setDefault() 。</span>
<span class="token comment">//但是,如果没有设置默认按钮并在使用 QPushButton::autoDefault </span>
<span class="token comment">//属性时保留哪个按钮是跨平台的默认按钮,则在显示 QDialogButtonBox 时,</span>
<span class="token comment">//第一个具有接受角色的按钮将成为默认按钮,</span>
<span class="token keyword">class</span> <span class="token class-name">QDialogButtonBox</span><span class="token punctuation">;</span>
<span class="token comment">//QLabel 用于显示文本或图像。</span>
<span class="token comment">//不提供用户交互功能。</span>
<span class="token comment">//标签的视觉外观可以通过多种方式配置,</span>
<span class="token comment">//它可以用于为另一个小部件指定一个焦点助记键。</span>
<span class="token comment">//QLabel 可以包含以下任何内容类型:</span>
<span class="token comment">//Plain text 将 QString 传递给 setText()。</span>
<span class="token comment">//Rich text 将包含富文本的 QString 传递给 setText()。</span>
<span class="token comment">//A pixmap 将 QPixmap 传递给 setPixmap()。</span>
<span class="token comment">//A movie 将 QMovie 传递给 setMovie()。</span>
<span class="token comment">//A number  将 int 或 double 传递给 setNum(),它将数字转换为纯文本</span>
<span class="token comment">//Nothing   与空的纯文本相同。 这是默认设置。 由 clear() 设置。</span>
<span class="token comment">//警告:当将 QString 传递给构造函数或调用 setText() 时,</span>
<span class="token comment">//请确保清理您的输入</span>
<span class="token comment">//因为 QLabel 会尝试猜测它是将文本显示为纯文本还是富文本(HTML 4 标记的子集)。</span>
<span class="token comment">//您可能希望显式调用 setTextFormat(),</span>
<span class="token comment">//例如 以防您希望文本为纯格式但无法控制文本源(例如,当显示从 Web 加载的数据时)。</span>
<span class="token comment">//当使用这些功能中的任何一个更改内容时,任何先前的内容都会被清除。</span>
<span class="token comment">//默认情况下,标签显示左对齐、垂直居中的文本和图像,</span>
<span class="token comment">//其中要显示的文本中的任何选项卡都会自动展开。</span>
<span class="token comment">//但是,可以通过多种方式调整和微调 QLabel 的外观。</span>
<span class="token comment">//可以使用 setAlignment() 和 setIndent() 调整 QLabel 小部件区域内内容的定位</span>
<span class="token comment">//文本内容还可以使用 setWordWrap() 沿单词边界换行。</span>
<span class="token comment">//例如,此代码在右下角设置了一个带有两行文本的下沉面板(两行与标签右侧齐平):</span>
<span class="token comment">/*
    QLabel *label = new QLabel(this);
    label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
    label->setText("first line\nsecond line");
    label->setAlignment(Qt::AlignBottom | Qt::AlignRight);
*/</span>
<span class="token comment">//QLabel 继承自 QFrame 的属性和函数也可用于指定要用于任何给定标签的小部件框架。</span>
<span class="token comment">//QLabel 通常用作交互式小部件的标签。</span>
<span class="token comment">//为此,QLabel 提供了一种有用的机制来添加助记符(请参阅 QKeySequence),</span>
<span class="token comment">//该助记符会将键盘焦点设置到其他小部件(称为 QLabel 的“伙伴”)。 例如:</span>
<span class="token comment">/*
    QLineEdit *phoneEdit = new QLineEdit(this);
    QLabel *phoneLabel = new QLabel("&Phone:",this);
    phoneLabel->setBuddy(phoneEdit);
*/</span>
<span class="token comment">//在此示例中,当用户按下 Alt+P 时,</span>
<span class="token comment">//键盘焦点将转移到标签的伙伴(QLineEdit)。</span>
<span class="token comment">//如果好友是一个按钮(从 QAbstractButton 继承),触发助记符将模拟按钮点击。</span>
<span class="token keyword">class</span> <span class="token class-name">QLabel</span><span class="token punctuation">;</span>
<span class="token comment">//工具按钮是一种特殊按钮,可提供对特定命令或选项的快速访问。</span>
<span class="token comment">//与普通命令按钮相反,工具按钮通常不显示文本标签,而是显示图标</span>
<span class="token comment">//当使用 QToolBar::addAction() 创建新的 QAction 实例或使用 QToolBar::addAction() 将现有操作添加到工具栏时,</span>
<span class="token comment">//通常会创建工具按钮。</span>
<span class="token comment">//也可以以与任何其他小部件相同的方式构建工具按钮,</span>
<span class="token comment">//并将它们与布局中的其他小部件一起排列</span>
<span class="token comment">//工具按钮的一种经典用法是选择工具</span>
<span class="token comment">//例如,绘图程序中的“钢笔”工具。</span>
<span class="token comment">//这将通过使用 QToolButton 作为切换按钮来实现(参见 setCheckable())。</span>
<span class="token comment">//QToolButton 支持自动提升。</span>
<span class="token comment">//在自动提升模式下该按钮仅在鼠标指向时绘制 3D 帧。</span>
<span class="token comment">//当在 QToolBar 中使用按钮时,该功能会自动打开。 使用 setAutoRaise() 更改它。</span>
<span class="token comment">//工具按钮的图标设置为 QIcon。</span>
<span class="token comment">//这使得可以为禁用和活动状态指定不同的像素图。</span>
<span class="token comment">//当按钮的功能不可用时,使用禁用的像素图。</span>
<span class="token comment">//由于鼠标指针悬停在按钮上而自动抬起按钮时,将显示活动像素图。</span>
<span class="token comment">//按钮的外观和尺寸可通过 setToolButtonStyle() 和 setIconSize() 进行调整。</span>
<span class="token comment">//当在 QMainWindow 的 QToolBar 内使用时,</span>
<span class="token comment">//按钮会自动调整到 QMainWindow 的设置</span>
<span class="token comment">//(参见 QMainWindow::setToolButtonStyle() 和 QMainWindow::setIconSize())。</span>
<span class="token comment">//除了图标,工具按钮还可以显示箭头符号,由 arrowType 指定。</span>
<span class="token comment">//工具按钮可以在弹出菜单中提供其他选项。</span>
<span class="token comment">//可以使用 setMenu() 设置弹出菜单。</span>
<span class="token comment">//使用 setPopupMode() 配置可用于带有菜单集的工具按钮的不同模式。</span>
<span class="token comment">//默认模式是 DelayedPopupMode,有时与 Web 浏览器中的“后退”按钮一起使用。</span>
<span class="token comment">//按住按钮一段时间后,会弹出一个菜单,显示要跳转到的可能页面列表。</span>
<span class="token comment">//超时取决于样式,请参阅 QStyle::SH_ToolButton_PopupDelay。</span>
<span class="token keyword">class</span> <span class="token class-name">QToolButton</span><span class="token punctuation">;</span>
<span class="token comment">//QTreeWidget 类是一个方便的类,它提供了一个标准的树形小部件,</span>
<span class="token comment">//它具有类似于 Qt 3 中的 QListView 类使用的经典的基于项目的界面。</span>
<span class="token comment">//这个类基于 Qt 的模型/视图架构,并使用默认模型来保存项目 ,每一个都是一个 QTreeWidgetItem。</span>
<span class="token comment">//不需要模型/视图框架灵活性的开发人员可以使用此类非常轻松地创建简单的分层列表。</span>
<span class="token comment">//更灵活的方法包括将 QTreeView 与标准项目模型相结合。</span>
<span class="token comment">//这允许将数据的存储与其表示分开。</span>
<span class="token comment">//在最简单的形式中,可以通过以下方式构建树小部件:</span>
<span class="token comment">/*
    QTreeWidget *treeWidget = new QTreeWidget();
    treeWidget->setColumnCount(1);
    QList<QTreeWidgetItem*> items;
    for(int i = 0;i < 10; ++i)
        items.append(new QTreeWidgetItem(static_cast<QTreeWidget*>(nullptr),QStringList(QString("item:%1").arg(i))));
    treeWidget->insertToLevelItems(0,items);
*/</span>
<span class="token comment">//在将项目添加到树小部件之前,必须使用 setColumnCount() 设置列数。</span>
<span class="token comment">//这允许每个项目有一个或多个标签或其他装饰。</span>
<span class="token comment">//使用的列数可以通过 columnCount() 函数找到。</span>
<span class="token comment">//树可以有一个标题,其中包含小部件中每一列的部分。</span>
<span class="token comment">//通过使用 setHeaderLabels() 提供字符串列表来为每个部分设置标签是最简单的,</span>
<span class="token comment">//但是可以使用 QTreeWidgetItem 构造自定义标题并使用 setHeaderItem() 函数将其插入到树中。</span>
<span class="token comment">//树中的项目可以根据预定义的排序顺序按列排序。</span>
<span class="token comment">//如果启用排序,用户可以通过单击列标题对项目进行排序。</span>
<span class="token comment">//可以通过调用 setSortingEnabled() 启用或禁用排序。</span>
<span class="token comment">//isSortingEnabled() 函数指示是否启用排序。</span>
<span class="token keyword">class</span> <span class="token class-name">QTreeWidget</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">QTreeWidgetItem</span><span class="token punctuation">;</span>
<span class="token comment">//树小部件项用于保存树小部件的信息行。</span>
<span class="token comment">//行通常包含几列数据,每列可以包含一个文本标签和一个图标。</span>
<span class="token comment">//QTreeWidgetItem 类是一个方便的类,</span>
<span class="token comment">//,它取代了 Qt 3 中的 QListViewItem 类。</span>
<span class="token comment">//它提供了一个与 QTreeWidget 类一起使用的项目。</span>
<span class="token comment">//项目通常由父级构造,该父级是 QTreeWidget(用于顶级项目)或 </span>
<span class="token comment">//QTreeWidgetItem(用于树较低级别的项目)</span>
<span class="token comment">//例如,下面的代码构造了一个顶级项来表示世界的城市,并添加了一个 Oslo 条目作为子项:</span>
<span class="token comment">/*
    QTreeWidgetItem* cities = new QTreeWidgetItem(treeWidget);
    cities->setText(0,tr("Cities"));
    QTreeWidgetItem* osloItem = new QTreeWidgetItem(cities);
    osloItem->setText(0,tr("Oslo"));
    osloItem->setText(1,tr("Yes"));
*/</span>
<span class="token comment">//通过指定它们在构造时遵循的项目,可以按特定顺序添加项目:</span>
<span class="token comment">/*
    QTreeWidgetItem *planes = new QTreeWidgetItem(treeWidget,cities);
    planets->setText(0,tr("Planets"));
*/</span>
<span class="token comment">//项目中的每一列都可以有自己的背景画笔,</span>
<span class="token comment">//该画笔是通过 setBackground() 函数设置的。</span>
<span class="token comment">//可以使用 background() 找到当前的背景画笔。</span>
<span class="token comment">//每列的文本标签可以使用自己的字体和画笔呈现。</span>
<span class="token comment">//这些是用 setFont() 和 setForeground() 函数指定的,并用 font() 和 foreground() 读取。</span>
<span class="token comment">//顶级项目与树中较低级别项目之间的主要区别在于顶级项目没有 parent()。</span>
<span class="token comment">//此信息可用于区分项目之间的差异,并且有助于了解何时从树中插入和删除项目。</span>
<span class="token comment">//可以使用 takeChild() 删除项的子项,并使用 insertChild() 函数将其插入到子项列表中的给定索引处。</span>
<span class="token comment">//默认情况下,项目是启用的、可选择的、可检查的,并且可以是拖放操作的来源。</span>
<span class="token comment">//可以通过使用适当的值调用 setFlags() 来更改每个项目的标志(请参阅 Qt::ItemFlags)。</span>
<span class="token comment">//可以使用 setCheckState() 函数选中和取消选中可检查项。</span>
<span class="token comment">//相应的 checkState() 函数指示该项目当前是否被选中。</span>
<span class="token comment">//子类化</span>
<span class="token comment">//当子类化 QTreeWidgetItem 以提供自定义项时,</span>
<span class="token comment">//,可以为它们定义新类型,以便将它们与标准项区分开来。</span>
<span class="token comment">//需要此功能的子类的构造函数需要使用等于或大于 UserType 的新类型值调用基类构造函数。</span>
QT_END_NAMESPACE

<span class="token keyword">class</span> <span class="token class-name">Assistant</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">TextEdit</span><span class="token punctuation">;</span>

<span class="token comment">//Simple Text Viewer 应用程序提供了一个查找文件对话框,</span>
<span class="token comment">//允许用户使用通配符匹配来搜索文件。</span>
<span class="token comment">//搜索在指定目录中执行,并且用户可以选择浏览现有文件系统以查找相关目录。</span>
<span class="token keyword">class</span> <span class="token class-name">FindFileDialog</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> <span class="token class-name">QDialog</span></span>
<span class="token punctuation">{</span>
    Q_OBJECT

<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token function">FindFileDialog</span><span class="token punctuation">(</span>TextEdit <span class="token operator">*</span>editor<span class="token punctuation">,</span> Assistant <span class="token operator">*</span>assistant<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">private</span> slots<span class="token operator">:</span>
    <span class="token keyword">void</span> <span class="token function">browse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">help</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">openFile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token keyword">void</span> <span class="token function">findFiles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">showFiles</span><span class="token punctuation">(</span><span class="token keyword">const</span> QStringList <span class="token operator">&</span>files<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">void</span> <span class="token function">createButtons</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">createComboBoxes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">createFilesTree</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">createLabels</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">createLayout</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    Assistant <span class="token operator">*</span>currentAssistant<span class="token punctuation">;</span>
    TextEdit <span class="token operator">*</span>currentEditor<span class="token punctuation">;</span>
    QTreeWidget <span class="token operator">*</span>foundFilesTree<span class="token punctuation">;</span>

    QComboBox <span class="token operator">*</span>directoryComboBox<span class="token punctuation">;</span>
    QComboBox <span class="token operator">*</span>fileNameComboBox<span class="token punctuation">;</span>

    QLabel <span class="token operator">*</span>directoryLabel<span class="token punctuation">;</span>
    QLabel <span class="token operator">*</span>fileNameLabel<span class="token punctuation">;</span>

    QDialogButtonBox <span class="token operator">*</span>buttonBox<span class="token punctuation">;</span>

    QToolButton <span class="token operator">*</span>browseButton<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">//! [0]</span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
</code></pre> 
  <p>findfiledialog.cpp</p> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"assistant.h"</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"findfiledialog.h"</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"textedit.h"</span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QComboBox></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QDialogButtonBox></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QDir></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QFileDialog></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QHBoxLayout></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QLabel></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QPushButton></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QRegularExpression></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QToolButton></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QTreeWidget></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QTreeWidgetItem></span></span>

<span class="token comment">//在构造函数中,我们保存对作为参数传递的 Assistant 和 QTextEdit 对象的引用。</span>
<span class="token comment">//Assistant 对象将在 FindFileDialog 的 help() 槽中使用</span>
<span class="token comment">//我们很快就会看到,而 QTextEdit 将在对话框的 openFile() 槽中使用以显示所选文件。</span>
<span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">FindFileDialog</span><span class="token punctuation">(</span>TextEdit <span class="token operator">*</span>editor<span class="token punctuation">,</span> Assistant <span class="token operator">*</span>assistant<span class="token punctuation">)</span>
    <span class="token operator">:</span> <span class="token function">QDialog</span><span class="token punctuation">(</span>editor<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    currentAssistant <span class="token operator">=</span> assistant<span class="token punctuation">;</span>
    currentEditor <span class="token operator">=</span> editor<span class="token punctuation">;</span>
<span class="token comment">//! [0]</span>

    <span class="token function">createButtons</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">createComboBoxes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">createFilesTree</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">createLabels</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">createLayout</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">//void QComboBox::addItem(const QString &text, const QVariant &userData = QVariant())</span>
    <span class="token comment">//使用给定的文本将一个项目添加到组合框</span>
    <span class="token comment">//并包含指定的 userData(存储在 Qt::UserRole 中)。</span>
    <span class="token comment">//该项目将附加到现有项目的列表中。</span>
    <span class="token comment">//[static] QString QDir::toNativeSeparators(const QString &pathName)</span>
    <span class="token comment">//返回 pathName ,其中“/”分隔符转换为适用于底层操作系统的分隔符。</span>
    <span class="token comment">//在 Windows 上, toNativeSeparators("c:/winnt/system32") 返回 "c:\winnt\system32"。</span>
    <span class="token comment">//返回的字符串可能与某些操作系统上的参数相同,例如在 Unix 上。</span>
    directoryComboBox<span class="token operator">-></span><span class="token function">addItem</span><span class="token punctuation">(</span><span class="token class-name">QDir</span><span class="token operator">::</span><span class="token function">toNativeSeparators</span><span class="token punctuation">(</span><span class="token class-name">QDir</span><span class="token operator">::</span><span class="token function">currentPath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    fileNameComboBox<span class="token operator">-></span><span class="token function">addItem</span><span class="token punctuation">(</span><span class="token string">"*"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">findFiles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">setWindowTitle</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Find File"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//! [1]</span>
<span class="token punctuation">}</span>
<span class="token comment">//! [1]</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">browse</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//此属性保存当前文本</span>
    <span class="token comment">//如果组合框可编辑,则当前文本为行编辑显示的值。</span>
    <span class="token comment">//否则,如果组合框为空或未设置当前项,则为当前项的值或空字符串。</span>
    QString currentDirectory <span class="token operator">=</span> directoryComboBox<span class="token operator">-></span><span class="token function">currentText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//[static] QString QFileDialog::getExistingDirectory(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = ShowDirsOnly)</span>
    <span class="token comment">//这是一个方便的静态函数,它将返回用户选择的现有目录。</span>
    <span class="token comment">/*
        QString dir = QFileDialog::getExistingDirectory(this,tr("Open Directory"),
                                                        "/home",
                                                        QFileDialog::ShowDirsOnly
                                                        |QFileDialog::DontResolveSymlinks);
    */</span>
    <span class="token comment">//此函数使用给定的父小部件创建一个模态文件对话框。</span>
    <span class="token comment">//如果 parent 不是 nullptr,对话框将显示在父小部件的中心。</span>
    <span class="token comment">//对话框的工作目录设置为dir,</span>
    <span class="token comment">//标题设置为caption。</span>
    <span class="token comment">//其中任何一个都可以是空字符串,在这种情况下,将分别使用当前目录和默认标题。</span>
    <span class="token comment">//options 参数包含有关如何运行对话框的各种选项,</span>
    <span class="token comment">//有关您可以传递的标志的更多信息,请参阅 QFileDialog::Option 枚举。</span>
    <span class="token comment">//为确保本机文件对话框,必须设置 ShowDirsOnly。</span>
    <span class="token comment">//在 Windows 和 macOS 上,此静态函数将使用本机文件对话框而不是 QFileDialog。</span>
    <span class="token comment">//但是,本机 Windows 文件对话框不支持在目录选择器中显示文件。</span>
    <span class="token comment">//您需要传递 DontUseNativeDialog 以使用 QFileDialog 显示文件。</span>
    <span class="token comment">//在 Unix/X11 上,文件对话框的正常行为是解析和遵循符号链接。</span>
    <span class="token comment">//例如,如果 /usr/tmp 是 /var/tmp 的符号链接,则在输入 /usr/tmp 后,文件对话框将更改为 /var/tmp。</span>
    <span class="token comment">//如果选项包含 DontResolveSymlinks,则文件对话框会将符号链接视为常规目录。</span>
    <span class="token comment">//在 Windows 上,对话框将旋转一个阻塞模式事件循环,该循环不会调度任何 QTimers,</span>
    <span class="token comment">//如果 parent 不是 nullptr,那么它将把对话框定位在父标题栏的正下方。</span>
    QString newDirectory <span class="token operator">=</span> <span class="token class-name">QFileDialog</span><span class="token operator">::</span><span class="token function">getExistingDirectory</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span>
                               <span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Select Directory"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> currentDirectory<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>newDirectory<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        directoryComboBox<span class="token operator">-></span><span class="token function">addItem</span><span class="token punctuation">(</span><span class="token class-name">QDir</span><span class="token operator">::</span><span class="token function">toNativeSeparators</span><span class="token punctuation">(</span>newDirectory<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//此属性保存组合框中当前项目的索引。</span>
        <span class="token comment">//插入或删除项目时,当前索引可以更改。</span>
        <span class="token comment">//默认情况下,对于空组合框或未设置当前项的组合框,此属性的值为 -1。</span>
        directoryComboBox<span class="token operator">-></span><span class="token function">setCurrentIndex</span><span class="token punctuation">(</span>directoryComboBox<span class="token operator">-></span><span class="token function">count</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">//FindFileDialog 类中最相关的成员是私有 help() 槽。</span>
<span class="token comment">//该插槽连接到对话框的帮助按钮</span>
<span class="token comment">//并通过调用助手的 showDocumentation() </span>
<span class="token comment">//函数将当前的 Qt 助手实例与对话框的文档一起带到前台</span>
<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">help</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    currentAssistant<span class="token operator">-></span><span class="token function">showDocumentation</span><span class="token punctuation">(</span><span class="token string">"filedialog.html"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">openFile</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">auto</span> item  <span class="token operator">=</span> foundFilesTree<span class="token operator">-></span><span class="token function">currentItem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>item<span class="token punctuation">)</span>
        <span class="token keyword">return</span><span class="token punctuation">;</span>

    QString fileName <span class="token operator">=</span> item<span class="token operator">-></span><span class="token function">text</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    QString path <span class="token operator">=</span> <span class="token function">QDir</span><span class="token punctuation">(</span>directoryComboBox<span class="token operator">-></span><span class="token function">currentText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">filePath</span><span class="token punctuation">(</span>fileName<span class="token punctuation">)</span><span class="token punctuation">;</span>

    currentEditor<span class="token operator">-></span><span class="token function">setContents</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">findFiles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    buttonBox<span class="token operator">-></span><span class="token function">button</span><span class="token punctuation">(</span>QDialogButtonBox<span class="token operator">::</span>Open<span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">setEnabled</span><span class="token punctuation">(</span>
            foundFilesTree<span class="token operator">-></span><span class="token function">topLevelItemCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">findFiles</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    QString wildCard <span class="token operator">=</span> fileNameComboBox<span class="token operator">-></span><span class="token function">currentText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>wildCard<span class="token punctuation">.</span><span class="token function">endsWith</span><span class="token punctuation">(</span><span class="token string">'*'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        wildCard <span class="token operator">+=</span> <span class="token string">'*'</span><span class="token punctuation">;</span>
    QRegularExpression <span class="token function">filePattern</span><span class="token punctuation">(</span><span class="token class-name">QRegularExpression</span><span class="token operator">::</span><span class="token function">wildcardToRegularExpression</span><span class="token punctuation">(</span>wildCard<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    QDir <span class="token function">directory</span><span class="token punctuation">(</span>directoryComboBox<span class="token operator">-></span><span class="token function">currentText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">const</span> QStringList allFiles <span class="token operator">=</span> directory<span class="token punctuation">.</span><span class="token function">entryList</span><span class="token punctuation">(</span>QDir<span class="token operator">::</span>Files <span class="token operator">|</span> QDir<span class="token operator">::</span>NoSymLinks<span class="token punctuation">)</span><span class="token punctuation">;</span>
    QStringList matchingFiles<span class="token punctuation">;</span>

    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> QString <span class="token operator">&</span>file <span class="token operator">:</span> allFiles<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>filePattern<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hasMatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            matchingFiles <span class="token operator"><<</span> file<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">showFiles</span><span class="token punctuation">(</span>matchingFiles<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">showFiles</span><span class="token punctuation">(</span><span class="token keyword">const</span> QStringList <span class="token operator">&</span>files<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    foundFilesTree<span class="token operator">-></span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> files<span class="token punctuation">.</span><span class="token function">count</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        QTreeWidgetItem <span class="token operator">*</span>item <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">QTreeWidgetItem</span><span class="token punctuation">(</span>foundFilesTree<span class="token punctuation">)</span><span class="token punctuation">;</span>
        item<span class="token operator">-></span><span class="token function">setText</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> files<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>files<span class="token punctuation">.</span><span class="token function">count</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span>
        foundFilesTree<span class="token operator">-></span><span class="token function">setCurrentItem</span><span class="token punctuation">(</span>foundFilesTree<span class="token operator">-></span><span class="token function">topLevelItem</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">createButtons</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    browseButton <span class="token operator">=</span> <span class="token keyword">new</span> QToolButton<span class="token punctuation">;</span>
    browseButton<span class="token operator">-></span><span class="token function">setText</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"..."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">connect</span><span class="token punctuation">(</span>browseButton<span class="token punctuation">,</span> <span class="token operator">&</span>QAbstractButton<span class="token operator">::</span>clicked<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">&</span>FindFileDialog<span class="token operator">::</span>browse<span class="token punctuation">)</span><span class="token punctuation">;</span>

    buttonBox <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">QDialogButtonBox</span><span class="token punctuation">(</span>QDialogButtonBox<span class="token operator">::</span>Open
                                     <span class="token operator">|</span> QDialogButtonBox<span class="token operator">::</span>Cancel
                                     <span class="token operator">|</span> QDialogButtonBox<span class="token operator">::</span>Help<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">connect</span><span class="token punctuation">(</span>buttonBox<span class="token punctuation">,</span> <span class="token operator">&</span>QDialogButtonBox<span class="token operator">::</span>accepted<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">&</span>FindFileDialog<span class="token operator">::</span>openFile<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">connect</span><span class="token punctuation">(</span>buttonBox<span class="token punctuation">,</span> <span class="token operator">&</span>QDialogButtonBox<span class="token operator">::</span>rejected<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">&</span>QDialog<span class="token operator">::</span>reject<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">connect</span><span class="token punctuation">(</span>buttonBox<span class="token punctuation">,</span> <span class="token operator">&</span>QDialogButtonBox<span class="token operator">::</span>helpRequested<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">&</span>FindFileDialog<span class="token operator">::</span>help<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">createComboBoxes</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    directoryComboBox <span class="token operator">=</span> <span class="token keyword">new</span> QComboBox<span class="token punctuation">;</span>
    fileNameComboBox <span class="token operator">=</span> <span class="token keyword">new</span> QComboBox<span class="token punctuation">;</span>

    fileNameComboBox<span class="token operator">-></span><span class="token function">setEditable</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    fileNameComboBox<span class="token operator">-></span><span class="token function">setSizePolicy</span><span class="token punctuation">(</span>QSizePolicy<span class="token operator">::</span>Expanding<span class="token punctuation">,</span>
                                    QSizePolicy<span class="token operator">::</span>Preferred<span class="token punctuation">)</span><span class="token punctuation">;</span>

    directoryComboBox<span class="token operator">-></span><span class="token function">setMinimumContentsLength</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    directoryComboBox<span class="token operator">-></span><span class="token function">setSizeAdjustPolicy</span><span class="token punctuation">(</span>
            QComboBox<span class="token operator">::</span>AdjustToContents<span class="token punctuation">)</span><span class="token punctuation">;</span>
    directoryComboBox<span class="token operator">-></span><span class="token function">setSizePolicy</span><span class="token punctuation">(</span>QSizePolicy<span class="token operator">::</span>Expanding<span class="token punctuation">,</span>
                                     QSizePolicy<span class="token operator">::</span>Preferred<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">connect</span><span class="token punctuation">(</span>fileNameComboBox<span class="token punctuation">,</span> <span class="token operator">&</span>QComboBox<span class="token operator">::</span>editTextChanged<span class="token punctuation">,</span>
            <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">&</span>FindFileDialog<span class="token operator">::</span>update<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">connect</span><span class="token punctuation">(</span>directoryComboBox<span class="token punctuation">,</span> <span class="token operator">&</span>QComboBox<span class="token operator">::</span>currentTextChanged<span class="token punctuation">,</span>
            <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">&</span>FindFileDialog<span class="token operator">::</span>update<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">createFilesTree</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    foundFilesTree <span class="token operator">=</span> <span class="token keyword">new</span> QTreeWidget<span class="token punctuation">;</span>
    foundFilesTree<span class="token operator">-></span><span class="token function">setColumnCount</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    foundFilesTree<span class="token operator">-></span><span class="token function">setHeaderLabels</span><span class="token punctuation">(</span><span class="token function">QStringList</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Matching Files"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    foundFilesTree<span class="token operator">-></span><span class="token function">setRootIsDecorated</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    foundFilesTree<span class="token operator">-></span><span class="token function">setSelectionMode</span><span class="token punctuation">(</span>QAbstractItemView<span class="token operator">::</span>SingleSelection<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">connect</span><span class="token punctuation">(</span>foundFilesTree<span class="token punctuation">,</span> <span class="token operator">&</span>QTreeWidget<span class="token operator">::</span>itemActivated<span class="token punctuation">,</span>
            <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">&</span>FindFileDialog<span class="token operator">::</span>openFile<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">createLabels</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    directoryLabel <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">QLabel</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Search in:"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    fileNameLabel <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">QLabel</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"File name (including wildcards):"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">FindFileDialog</span><span class="token operator">::</span><span class="token function">createLayout</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    QHBoxLayout <span class="token operator">*</span>fileLayout <span class="token operator">=</span> <span class="token keyword">new</span> QHBoxLayout<span class="token punctuation">;</span>
    fileLayout<span class="token operator">-></span><span class="token function">addWidget</span><span class="token punctuation">(</span>fileNameLabel<span class="token punctuation">)</span><span class="token punctuation">;</span>
    fileLayout<span class="token operator">-></span><span class="token function">addWidget</span><span class="token punctuation">(</span>fileNameComboBox<span class="token punctuation">)</span><span class="token punctuation">;</span>

    QHBoxLayout <span class="token operator">*</span>directoryLayout <span class="token operator">=</span> <span class="token keyword">new</span> QHBoxLayout<span class="token punctuation">;</span>
    directoryLayout<span class="token operator">-></span><span class="token function">addWidget</span><span class="token punctuation">(</span>directoryLabel<span class="token punctuation">)</span><span class="token punctuation">;</span>
    directoryLayout<span class="token operator">-></span><span class="token function">addWidget</span><span class="token punctuation">(</span>directoryComboBox<span class="token punctuation">)</span><span class="token punctuation">;</span>
    directoryLayout<span class="token operator">-></span><span class="token function">addWidget</span><span class="token punctuation">(</span>browseButton<span class="token punctuation">)</span><span class="token punctuation">;</span>

    QVBoxLayout <span class="token operator">*</span>mainLayout <span class="token operator">=</span> <span class="token keyword">new</span> QVBoxLayout<span class="token punctuation">;</span>
    mainLayout<span class="token operator">-></span><span class="token function">addLayout</span><span class="token punctuation">(</span>fileLayout<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mainLayout<span class="token operator">-></span><span class="token function">addLayout</span><span class="token punctuation">(</span>directoryLayout<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mainLayout<span class="token operator">-></span><span class="token function">addWidget</span><span class="token punctuation">(</span>foundFilesTree<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mainLayout<span class="token operator">-></span><span class="token function">addStretch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mainLayout<span class="token operator">-></span><span class="token function">addWidget</span><span class="token punctuation">(</span>buttonBox<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">setLayout</span><span class="token punctuation">(</span>mainLayout<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p>assistant.h</p> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">ASSISTANT_H</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ASSISTANT_H</span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QCoreApplication></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QProcess></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QScopedPointer></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QString></span></span>

<span class="token comment">//通过 Assistant 类控制 Qt Assistant</span>
<span class="token comment">//我们将首先看看如何从远程应用程序启动和操作 Qt 助手。 为此,我们创建了一个名为 Assistant 的类。</span>
<span class="token comment">//此类提供了一个用于显示文档页面的公共函数,</span>
<span class="token comment">//以及一个用于确保 Qt Assistant 启动并运行的私有帮助函数。</span>
<span class="token keyword">class</span> <span class="token class-name">Assistant</span>
<span class="token punctuation">{</span>
    <span class="token comment">//Q_DECLARE_TR_FUNCTIONS(context)</span>
    <span class="token comment">//Q_DECLARE_TR_FUNCTIONS() 宏使用以下签名声明并实现了转换函数 tr():</span>
    <span class="token comment">/*
        static inline QString tr(const char* sourceText,
                                 const char* comment = nullptr);
    */</span>
    <span class="token comment">//如果您想在不继承自 QObject 的类中使用 QObject::tr(),则此宏很有用。</span>
    <span class="token comment">//Q_DECLARE_TR_FUNCTIONS() 必须出现在类定义的最顶部(在第一个 public: 或 protected: 之前)。 例如:</span>
    <span class="token comment">/*
        class MyMfcView : public CView
        {
            Q_CECLARE_TR_FUNCTIONS(MyMfcView);
        public:
            MyMfcView();
            ....
        }
        //上下文参数通常是类名,但它可以是任何文本。
    */</span>
    <span class="token function">Q_DECLARE_TR_FUNCTIONS</span><span class="token punctuation">(</span>Assistant<span class="token punctuation">)</span>

<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token function">Assistant</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">~</span><span class="token function">Assistant</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">showDocumentation</span><span class="token punctuation">(</span><span class="token keyword">const</span> QString <span class="token operator">&</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token keyword">bool</span> <span class="token function">startAssistant</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">showError</span><span class="token punctuation">(</span><span class="token keyword">const</span> QString <span class="token operator">&</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//运行进程</span>
    <span class="token comment">//要启动进程,请将要运行的程序的名称和命令行参数作为参数传递给 start()。</span>
    <span class="token comment">//参数作为 QStringList 中的单个字符串提供。</span>
    <span class="token comment">//或者,您可以将程序设置为使用 setProgram() 和 setArguments() 运行,然后调用 start() 或 open()。</span>
    <span class="token comment">//例如,以下代码片段通过将包含“-style”和“fusion”的字符串作为参数列表中的两个项目传递,</span>
    <span class="token comment">//在 X11 平台上以 Fusion 风格运行模拟时钟示例:</span>
    <span class="token comment">/*
        QObject *parent;
        ...
        QString program = "./path/to/Qt/examples/widgets/analogclock";
        QStringList arguments;
        arguments << "-style"<<"fusion";

        QProcess *myProcess = new QProcess(parent);
        myProcess->start(program,arguments);
    */</span>
    <span class="token comment">//然后QProcess 进入Starting 状态,当程序启动后,QProcess 进入Running 状态并发出started()。</span>
    <span class="token comment">//QProcess 允许您将进程视为顺序 I/O 设备。</span>
    <span class="token comment">//您可以像使用 QTcpSocket 访问网络连接一样对进程进行写入和读取。</span>
    <span class="token comment">//然后,您可以通过调用 write() 写入进程的标准输入,</span>
    <span class="token comment">//通过调用 read()、readLine() 和 getChar() 读取标准输出。</span>
    <span class="token comment">//因为它继承了QIODevice,所以QProcess也可以作为QXmlReader的输入源,</span>
    <span class="token comment">//或者用于生成要使用QNetworkAccessManager上传的数据。</span>
    <span class="token comment">//当进程退出时,QProcess 重新进入NotRunning 状态(初始状态),并发出finished()。</span>
    <span class="token comment">//Finished() 信号提供进程的退出代码和退出状态作为参数,</span>
    <span class="token comment">//您还可以调用 exitCode() 获取最后一个完成的进程的退出代码,并调用 exitStatus() 获取其退出状态。</span>
    <span class="token comment">//如果在任何时间点发生错误,QProcess 将发出 errorOccurred() 信号。</span>
    <span class="token comment">//您还可以调用 error() 来查找最后发生的错误类型,并调用 state() 来查找当前进程状态。</span>
    <span class="token comment">//Communicating via Channels</span>
    <span class="token comment">//进程有两个预定义的输出通道:</span>
    <span class="token comment">//标准输出通道 (stdout) 提供常规控制台输出,标准错误通道 (stderr) 通常提供进程打印的错误。 这些通道代表两个独立的数据流。</span>
    <span class="token comment">//您可以通过调用 setReadChannel() 在它们之间切换。</span>
    <span class="token comment">//当当前读取通道上的数据可用时,QProcess 会发出 readyRead()。</span>
    <span class="token comment">//当新的标准输出数据可用时,它也会发出 readyReadStandardOutput(),</span>
    <span class="token comment">//当新的标准错误数据可用时,会发出 readyReadStandardError()。</span>
    <span class="token comment">//除了调用 read()、readLine() 或 getChar(),您还可以通过调用 </span>
    <span class="token comment">//readAllStandardOutput() 或 readAllStandardError() 从两个通道中的任何一个显式读取所有数据。</span>
    <span class="token comment">//渠道的术语可能会产生误导。</span>
    <span class="token comment">//请注意,进程的输出通道对应于 QProcess 的读取通道,而进程的输入通道对应于 QProcess 的写入通道。</span>
    <span class="token comment">//这是因为我们使用 QProcess 读取的是进程的输出,而我们写入的则成为进程的输入。</span>
    <span class="token comment">//QProcess 可以合并两个输出通道,这样来自运行进程的标准输出和标准错误数据都使用标准输出通道。</span>
    <span class="token comment">//在开始激活此功能的过程之前,使用 MergedChannels 调用 setProcessChannelMode()。</span>
    <span class="token comment">//通过将 ForwardedChannels 作为参数传递,</span>
    <span class="token comment">//您还可以选择将正在运行的进程的输出转发到调用主进程。</span>
    <span class="token comment">//也可以只转发一个输出通道——通常会使用 ForwardedErrorChannel,</span>
    <span class="token comment">//但 ForwardedOutputChannel 也存在。</span>
    <span class="token comment">//请注意,在 GUI 应用程序中使用通道转发通常是一个坏主意 - 您应该以图形方式显示错误。</span>
    <span class="token comment">//。QProcess 可以合并两个输出通道,以便来自正在运行的进程的标准输出和标准错误数据都使用标准输出通道。</span>
    <span class="token comment">//在开始激活此功能的过程之前,使用 MergedChannels 调用 setProcessChannelMode()。</span>
    <span class="token comment">//通过将 ForwardedChannels 作为参数传递,您还可以选择将正在运行的进程的输出转发到调用主进程。</span>
    <span class="token comment">//也可以只转发一个输出通道——通常会使用 ForwardedErrorChannel,</span>
    <span class="token comment">//但 ForwardedOutputChannel 也存在。</span>
    <span class="token comment">//请注意,在 GUI 应用程序中使用通道转发通常是一个坏主意 - 您应该改为以图形方式显示错误。</span>
    <span class="token comment">//某些进程需要特殊的环境设置才能运行。</span>
    <span class="token comment">//您可以通过调用 setProcessEnvironment() 为您的进程设置环境变量。</span>
    <span class="token comment">//要设置工作目录,请调用 setWorkingDirectory()。</span>
    <span class="token comment">//默认情况下,进程在调用进程的当前工作目录中运行。</span>
    <span class="token comment">//属于使用 QProcess 启动的 GUI 应用程序的窗口的定位和屏幕 Z 顺序由底层窗口系统控制。</span>
    <span class="token comment">//对于 Qt 5 应用程序,可以使用 -qwindowgeometry 命令行选项指定定位;</span>
    <span class="token comment">//X11 应用程序通常接受 -geometry 命令行选项。</span>
    <span class="token comment">//注意:在 QNX 上,由于操作系统的限制,设置工作目录可能会导致除 QProcess 调用者线程之外的所有应用程序线程在生成过程中暂时冻结。</span>
    <span class="token comment">//Synchronous Process API</span>
    <span class="token comment">//QProcess 提供了一组函数,允许它在没有事件循环的情况下使用,通过挂起调用线程直到发出某些信号:</span>
    <span class="token comment">//waitForStarted() 阻塞直到进程启动。</span>
    <span class="token comment">//waitForReadyRead() 阻塞,直到新数据可用于在当前读取通道上读取。</span>
    <span class="token comment">//waitForBytesWritten() 阻塞,直到一个有效负载的数据写入进程。</span>
    <span class="token comment">//waitForFinished() 阻塞直到进程完成。</span>
    <span class="token comment">//从主线程(调用 QApplication::exec() 的线程)调用这些函数可能会导致您的用户界面冻结。</span>
    <span class="token comment">//下面的示例运行 gzip 来压缩字符串“Qt Rocks!”,没有事件循环:</span>
    <span class="token comment">/*
        QProcess gzip;
        gzip.start("gzip",QStringList()<<"-c");
        if(!gzip.waitForStarted())
            return false;

        gzip.write("Qt rocks!");
        gzip.closeWriteChannel();

        if(!gzip.waitForFinished())
            return false;
        QByteArray result = gzip.readAll();
    */</span>
    <span class="token comment">//Notes for Windows Users</span>
    <span class="token comment">//某些 Windows 命令(例如 dir)不是由单独的应用程序提供,而是由命令解释器本身提供。</span>
    <span class="token comment">//如果您尝试使用 QProcess 直接执行这些命令,它将不起作用。</span>
    <span class="token comment">//一种可能的解决方案是执行命令解释器本身(某些 Windows 系统上的 cmd.exe),并要求解释器执行所需的命令。</span>
    <span class="token keyword">void</span> <span class="token function">finished</span><span class="token punctuation">(</span><span class="token keyword">int</span> exitCode<span class="token punctuation">,</span> QProcess<span class="token operator">::</span>ExitStatus status<span class="token punctuation">)</span><span class="token punctuation">;</span>
    QScopedPointer<span class="token operator"><</span>QProcess<span class="token operator">></span> m_process<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
</code></pre> 
  <p>assistant.cpp</p> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"assistant.h"</span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QApplication></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QByteArray></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QDir></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QLibraryInfo></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QMessageBox></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><QStandardPaths></span></span>

<span class="token class-name">Assistant</span><span class="token operator">::</span><span class="token function">Assistant</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">default</span><span class="token punctuation">;</span>

<span class="token comment">//[static] bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)</span>
<span class="token comment">//断开对象发送方中的信号与对象接收方中的方法的连接。</span>
<span class="token comment">//如果连接成功断开,则返回 true; 否则返回false。</span>
<span class="token comment">//当所涉及的任何一个对象被破坏时,信号槽连接就会被移除。</span>
<span class="token comment">//disconnect() 通常以三种方式使用,如以下示例所示。</span>
<span class="token comment">//断开所有连接到对象信号的连接</span>
<span class="token comment">/*
    disconnect(myObject,nullptr,nullptr,nullptr)
*/</span>
<span class="token comment">//相当于非静态重载函数</span>
<span class="token comment">// myObject->disconnect();</span>

<span class="token comment">//断开所有连接到特定信号的东西</span>
<span class="token comment">//disconnect(myObject,SIGNAL(mySignal()),nullptr,nullptr);</span>
<span class="token comment">//相当于非静态重载函数</span>
<span class="token comment">//myObject->disconnect(SIGNAL(mySignal()));</span>
<span class="token comment">//断开特定接收器</span>
<span class="token comment">//disconnect(myObject,nullptr,myReceiver,nullptr);</span>
<span class="token comment">//相当于非静态重载函数</span>
<span class="token comment">//myObject->disconnect(myReceiver);</span>
<span class="token comment">//nullptr 可以用作通配符,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何插槽”。</span>
<span class="token comment">//发件人可能永远不会是 nullptr。 (您不能在一次调用中断开来自多个对象的信号。)</span>
<span class="token comment">//如果信号是 nullptr,它会断开接收器和方法与任何信号的连接。 如果不是,则仅断开指定的信号。</span>
<span class="token comment">//如果接收器是 nullptr,它会断开连接到信号的任何东西。 如果不是,则不会断开接收器以外的对象中的插槽。</span>
<span class="token comment">//如果 method 是 nullptr,它会断开连接到接收器的任何东西。 </span>
<span class="token comment">//如果没有,只有名为 method 的插槽将被断开连接,而所有其他插槽都将保持不变。 如果忽略接收器,则该方法必须为 nullptr,因此您无法断开所有对象上特定命名的插槽。</span>

<span class="token comment">//最后,我们确保 Qt Assistant 在应用程序关闭的情况下正确终止。</span>
<span class="token comment">//QProcess 的析构函数会终止进程,这意味着应用程序无法执行诸如保存用户设置之类的操作,这会导致设置文件损坏。</span>
<span class="token comment">//为了避免这种情况,我们要求 Qt Assistant 在 Assistant 类的析构函数中终止。</span>
<span class="token class-name">Assistant</span><span class="token operator">::</span><span class="token operator">~</span><span class="token function">Assistant</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>m_process<span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&&</span> m_process<span class="token operator">-></span><span class="token function">state</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> QProcess<span class="token operator">::</span>Running<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">QObject</span><span class="token operator">::</span><span class="token function">disconnect</span><span class="token punctuation">(</span>m_process<span class="token punctuation">.</span><span class="token function">data</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>QProcess<span class="token operator">::</span>finished<span class="token punctuation">,</span> <span class="token keyword">nullptr</span><span class="token punctuation">,</span> <span class="token keyword">nullptr</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//[slot] void QProcess::terminate()</span>
        <span class="token comment">//尝试终止进程。</span>
        <span class="token comment">//该进程可能不会因调用此函数而退出(它有机会提示用户输入任何未保存的文件等)。</span>
        <span class="token comment">//在 Windows 上,terminate() 将 WM_CLOSE 消息发送到进程的所有顶级窗口,然后发送到进程本身的主线程。</span>
        <span class="token comment">//在 Unix 和 macOS 上发送 SIGTERM 信号。</span>
        m_process<span class="token operator">-></span><span class="token function">terminate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//bool QProcess::waitForFinished(int msecs = 30000)</span>
        <span class="token comment">//阻塞直到进程完成并发出了 finished() 信号,或者直到经过了 msecs 毫秒。</span>
        <span class="token comment">//如果进程完成则返回真;</span>
        <span class="token comment">//否则返回 false(如果操作超时,如果发生错误,或者如果这个 QProcess 已经完成)。</span>
        <span class="token comment">//这个函数可以在没有事件循环的情况下运行。</span>
        <span class="token comment">//在编写非 GUI 应用程序和在非 GUI 线程中执行 I/O 操作时,它很有用。</span>
        m_process<span class="token operator">-></span><span class="token function">waitForFinished</span><span class="token punctuation">(</span><span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//showDocumentation() 的实现现在很简单。</span>
<span class="token comment">//首先,我们确保 Qt Assistant 正在运行</span>
<span class="token comment">//然后我们通过进程的 stdin 通道发送显示页面的请求</span>
<span class="token comment">//此处非常重要的是,该命令由行尾标记终止以刷新通道。</span>
<span class="token keyword">void</span> <span class="token class-name">Assistant</span><span class="token operator">::</span><span class="token function">showDocumentation</span><span class="token punctuation">(</span><span class="token keyword">const</span> QString <span class="token operator">&</span>page<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">startAssistant</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token keyword">return</span><span class="token punctuation">;</span>

    QByteArray <span class="token function">ba</span><span class="token punctuation">(</span><span class="token string">"SetSource "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    ba<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token string">"qthelp://org.qt-project.examples.simpletextviewer/doc/"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//qint64 QIODevice::write(const char *data, qint64 maxSize)</span>
    <span class="token comment">//最多将 maxSize 个字节的数据从 data 写入设备。</span>
    <span class="token comment">//返回实际写入的字节数,如果发生错误,则返回 -1。</span>
    m_process<span class="token operator">-></span><span class="token function">write</span><span class="token punctuation">(</span>ba <span class="token operator">+</span> page<span class="token punctuation">.</span><span class="token function">toLocal8Bit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//! [1]</span>

QString <span class="token function">documentationDirectory</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//QStringList 继承自 QList<QString>。</span>
    <span class="token comment">//与 QList 一样,QStringList 也是隐式共享的。</span>
    <span class="token comment">//它提供基于索引的快速访问以及快速插入和删除。</span>
    <span class="token comment">//将字符串列表作为值参数传递既快速又安全。</span>
    <span class="token comment">//QList 的所有功能也适用于 QStringList。</span>
    <span class="token comment">//例如可以使用isEmpty()来测试列表是否为空,可以调用append()、prepend()、</span>
    <span class="token comment">//insert()、replace()、removeAll()、removeAt()、removeFirst()等函数 、removeLast() 和 removeOne() 来修改 QStringList。</span>
    <span class="token comment">//QStringList 提供了一些方便的函数,使处理字符串列表更容易:</span>
    <span class="token comment">//Initializing</span>
    <span class="token comment">//默认构造函数创建一个空列表。</span>
    <span class="token comment">//您可以使用 initializer-list 构造函数来创建一个包含元素的列表:</span>
    <span class="token comment">//QStringList fonts = {"Arial","Helvetica","Times"};</span>
    <span class="token comment">//Adding Strings</span>
    <span class="token comment">//可以使用 insert()、append()、operator+=() 和 operator<<() 函数将字符串添加到列表中。</span>
    <span class="token comment">//operator<<() 可用于方便地将多个元素添加到列表中:</span>
    <span class="token comment">//fonts << "Couries"<<"Verdana";</span>
    <span class="token comment">//遍历字符串</span>
    <span class="token comment">//要迭代列表,您可以使用索引位置或 QList 的 Java 样式和 STL 样式迭代器类型:</span>
    <span class="token comment">/*
        for(int i = 0; i < fonts.size();++i)
            cout<<fonts.at(i).toLocal8bit().constData()<<Qt::endl;
    */</span>
    <span class="token comment">//Java-style iterator:</span>
    <span class="token comment">/*
        QStringListIterator javaStyleIterator(fonts);
        while(javaStyleIterator.hasNext())
            cout<<javaStyleIterator.next().toLocal8Bit().constData()<<Qt::endl;
    */</span>
    <span class="token comment">//STL-style iterator:</span>
    <span class="token comment">/*
        QStringList::const_iterator constIterator;
        for(constIterator = fonts.constBegin();constIterator!=fonts.constEnd();
            ++constIterator)
        cout<<(*constIterator).toLocal8Bit().constData()<<Qt::endl;
    */</span>
    <span class="token comment">//QStringListIterator 类只是 QListIterator<QString> 的类型定义。</span>
    <span class="token comment">//QStringList 还提供了 QMutableStringListIterator 类,它是 QMutableListIterator<QString> 的类型定义。</span>
    <span class="token comment">//Manipulating the Strings</span>
    <span class="token comment">//QStringList 提供了几个函数,允许您操作列表的内容。</span>
    <span class="token comment">//您可以使用 join() 函数将字符串列表中的所有字符串连接成一个字符串(带有可选的分隔符)。 例如:</span>
    <span class="token comment">/*
        QString str = fonts.join(", ");
        //str == "Arial,Helvetica,Times,Courier"
    */</span>
    <span class="token comment">//join 的参数可以是单个字符或字符串。</span>
    <span class="token comment">//要将字符串分解为字符串列表,请使用 QString::split() 函数:</span>
    <span class="token comment">/*
        QStringList list;
        list = str.split(',');
        //list:["Arial","Helvetica","Times","Courier"]
    */</span>
    <span class="token comment">//split 的参数可以是单个字符、字符串或 QRegularExpression。</span>
    <span class="token comment">//此外,operator+() 函数允许您将两个字符串列表连接为一个。 要对字符串列表进行排序,请使用 sort() 函数。</span>
    <span class="token comment">//QString list 还提供了 filter() 函数,它允许您提取一个新列表,</span>
    <span class="token comment">//该列表仅包含那些包含特定子字符串(或匹配特定正则表达式)的字符串:</span>
    <span class="token comment">//QStringList monospacedFonts = fonts.filter(QRegularExpression("Courier|Fixed"));</span>
    <span class="token comment">//contains() 函数告诉您列表是否包含给定字符串</span>
    <span class="token comment">//而 indexOf() 函数返回给定字符串第一次出现的索引。</span>
    <span class="token comment">//另一方面,lastIndexOf() 函数返回字符串最后一次出现的索引。</span>
    <span class="token comment">//最后,replaceInStrings() 函数依次对字符串列表中的每个字符串调用 QString::replace()。 例如:</span>
    <span class="token comment">/*
        QStringList files;
        files<<"$QTDIR/src/moc/moc.y"
             <<"$QTDIR/src/moc/moc.1"
             <<"$QTDIR/include/qconfig.h"

        files.replaceInStrings("$QTDIR","/usr/lib/qt");
        //files:["/usr/lib/qt/src/moc/moc.y",...]
    */</span>
    QStringList paths<span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">SRCDIR</span></span>
    paths<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">QLatin1String</span><span class="token punctuation">(</span>SRCDIR<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    paths<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token class-name">QLibraryInfo</span><span class="token operator">::</span><span class="token function">path</span><span class="token punctuation">(</span>QLibraryInfo<span class="token operator">::</span>ExamplesPath<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    paths<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token class-name">QCoreApplication</span><span class="token operator">::</span><span class="token function">applicationDirPath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//[static] QStringList QStandardPaths::standardLocations(QStandardPaths::StandardLocation type)</span>
    <span class="token comment">//返回类型文件所属的所有目录。</span>
    <span class="token comment">//目录列表从高优先级到低优先级排序,如果可以确定,</span>
    <span class="token comment">//则从 writableLocation() 开始。 如果未定义类型的位置,则此列表为空。</span>
    paths<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token class-name">QStandardPaths</span><span class="token operator">::</span><span class="token function">standardLocations</span><span class="token punctuation">(</span>QStandardPaths<span class="token operator">::</span>AppDataLocation<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//[since 5.7] template <typename T> typename std::add_const<T>::type &qAsConst(T &t)</span>
    <span class="token comment">//将 t 强制转换为 const T。</span>
    <span class="token comment">//这个函数是 C++17 的 std::as_const() 的 Qt 实现,一个类似于 std::move() 的强制转换函数。</span>
    <span class="token comment">//但是当 std::move() 将左值转换为右值时,该函数将非常量左值转换为常量左值</span>
    <span class="token comment">//像 std::as_const() 一样,它不适用于右值,因为它不能在不留下悬空引用的情况下有效地实现右值。</span>
    <span class="token comment">//它在 Qt 中的主要用途是防止隐式共享的 Qt 容器分离:  </span>
    <span class="token comment">/*
        QString s = ...;
        for(QChar ch : s) //detaches 's' (performs  a deep-copy if 's' was shared)
            process(ch);
        for(QChar ch : qAsConst(s)) //ok,no detach attempt
            process(ch);        
    */</span> 
    <span class="token comment">//当然,在这种情况下,您可以(并且可能应该)首先将 s 声明为 const:</span>
    <span class="token comment">/*
        const Qstring s = ...;
        for(QChar ch:s) //ok,no detach attempt on const objects
            process(ch);
    */</span>
    <span class="token comment">//但通常这并不容易。</span>
    <span class="token comment">//重要的是要注意 qAsConst() 不复制它的参数,</span>
    <span class="token comment">//它只是执行一个 const_cast<const T&>(t)。</span>
    <span class="token comment">//这也是它被设计为对右值失败的原因:返回的引用很快就会过时。 </span>
    <span class="token comment">//因此,虽然这有效(但分离了返回的对象):</span>
    <span class="token comment">/*
        for(QChar ch : funcReturningQString())
            process(ch); //ok,the returned object is kept alive for the loop's duration
    这不会:
        for(QChar ch : qAsConst(funcReturningQString()))
            process(ch); //ERROR: ch is copied from deleted memory
    
        //为了防止这个构造被编译(并在运行时失败),qAsConst() 有第二个已删除的重载,它绑定到右值。
    */</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span> <span class="token operator">&</span>dir <span class="token operator">:</span> <span class="token function">qAsConst</span><span class="token punctuation">(</span>paths<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">const</span> QString path <span class="token operator">=</span> dir <span class="token operator">+</span> <span class="token function">QLatin1String</span><span class="token punctuation">(</span><span class="token string">"/documentation"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">QFileInfo</span><span class="token operator">::</span><span class="token function">exists</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token keyword">return</span> path<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token function">QString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


<span class="token comment">//启动 Qt 助手是在函数 startAssistant() 中通过简单地创建和启动 QProcess 来完成的。</span>
<span class="token comment">//如果进程已经在运行,函数会立即返回。 否则,必须设置并启动该过程。</span>
<span class="token comment">//要启动该过程,我们需要 Qt Assistant 的可执行名称以及在自定义模式下运行 </span>
<span class="token comment">//Qt Assistant 的命令行参数。</span>
<span class="token comment">//可执行文件的名称有点棘手,因为它取决于平台,但幸运的是它只在 macOS 上有所不同。</span>
<span class="token comment">//可以在启动 Qt 助手时使用 -collectionFile 命令行参数更改显示的文档。</span>
<span class="token comment">//在没有任何选项的情况下启动时,Qt Assistant 会显示一组默认的文档。</span>
<span class="token comment">//安装 Qt 时,Qt Assistant 中的默认文档集包含 Qt 参考文档以及 Qt 附带的工具,例如 Qt Designer 和 qmake。</span>
<span class="token comment">//在我们的示例中,我们通过将特定于应用程序的集合文件传递给进程的命令行选项,用自定义文档替换默认文档集。</span>
<span class="token comment">//作为最后一个参数,我们添加了 -enableRemoteControl,它使 Qt Assistant 侦听其 stdin 通道的命令</span>
<span class="token comment">//,例如显示文档中某个页面的命令。</span>
<span class="token comment">//然后我们启动进程并等待它实际运行。 </span>
<span class="token comment">//如果由于某种原因无法启动 Qt Assistant,startAssistant() 将返回 false。</span>
<span class="token keyword">bool</span> <span class="token class-name">Assistant</span><span class="token operator">::</span><span class="token function">startAssistant</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>m_process<span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//[virtual] bool QIODevice::reset()</span>
        <span class="token comment">//seek到随机访问设备的输入开始。成功返回真; 否则返回 false(例如,如果设备未打开)。</span>
        <span class="token comment">//请注意,在 QFile 上使用 QTextStream 时,在 QFile 上调用 reset() 不会得到预期的结果,</span>
        <span class="token comment">//因为 QTextStream 会缓冲文件。 改用 QTextStream::seek() 函数。</span>
        m_process<span class="token punctuation">.</span><span class="token function">reset</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">QProcess</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//[signal] void QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus = NormalExit)</span>
        <span class="token comment">//该信号在进程完成时发出。 exitCode是进程的退出码(只对正常退出有效),exitStatus是退出状态。</span>
        <span class="token comment">//进程完成后,QProcess 中的缓冲区仍然完好无损。</span>
        <span class="token comment">//您仍然可以读取进程在完成之前可能已写入的任何数据。</span>
        <span class="token class-name">QObject</span><span class="token operator">::</span><span class="token function">connect</span><span class="token punctuation">(</span>m_process<span class="token punctuation">.</span><span class="token function">data</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>QProcess<span class="token operator">::</span>finished<span class="token punctuation">,</span>
                         m_process<span class="token punctuation">.</span><span class="token function">data</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> exitCode<span class="token punctuation">,</span> QProcess<span class="token operator">::</span>ExitStatus status<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                             <span class="token keyword">this</span><span class="token operator">-></span><span class="token function">finished</span><span class="token punctuation">(</span>exitCode<span class="token punctuation">,</span> status<span class="token punctuation">)</span><span class="token punctuation">;</span>
                         <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">//该进程正在运行并准备好进行读取和写入。</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>m_process<span class="token operator">-></span><span class="token function">state</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> QProcess<span class="token operator">::</span>Running<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//许多信息是在配置和构建 Qt 时建立的。</span>
        <span class="token comment">//此类提供访问该信息的抽象。</span>
        <span class="token comment">//通过使用此类的静态函数,应用程序可以获得有关应用程序在运行时使用的 Qt 库实例的信息。</span>
        <span class="token comment">//QLibraryInfo::BinariesPath</span>
        <span class="token comment">//安装 Qt 二进制文件(工具和应用程序)的路径。</span>
        QString app <span class="token operator">=</span> <span class="token class-name">QLibraryInfo</span><span class="token operator">::</span><span class="token function">path</span><span class="token punctuation">(</span>QLibraryInfo<span class="token operator">::</span>BinariesPath<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">Q_OS_DARWIN</span></span>
        app <span class="token operator">+=</span> <span class="token function">QLatin1String</span><span class="token punctuation">(</span><span class="token string">"/assistant"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">else</span></span>
        app <span class="token operator">+=</span> <span class="token function">QLatin1String</span><span class="token punctuation">(</span><span class="token string">"/Assistant.app/Contents/MacOS/Assistant"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>

        <span class="token keyword">const</span> QString collectionDirectory <span class="token operator">=</span> <span class="token function">documentationDirectory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>collectionDirectory<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token function">showError</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"The documentation directory cannot be found"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">//许多 QString 的成员函数被重载以接受 const char * 而不是 QString。</span>
        <span class="token comment">//这包括复制构造函数、赋值运算符、比较运算符以及各种其他函数,例如 insert()、replace() 和 indexOf()。</span>
        <span class="token comment">//这些函数通常经过优化,以避免为 const char * 数据构造 QString 对象。 例如,假设 str 是一个 QString,        </span>
        <span class="token comment">//定义 QT_NO_CAST_FROM_ASCII 的应用程序(如 QString 文档中所述)无法访问 QString 的 const char * API。</span>
        <span class="token comment">//了提供一种指定常量 Latin-1 字符串的有效方法,Qt 提供了 QLatin1String,它只是一个非常薄的 const char * 包装器。 使用QLatin1String,上面的示例代码变成</span>
        QStringList args<span class="token punctuation">{</span><span class="token function">QLatin1String</span><span class="token punctuation">(</span><span class="token string">"-collectionFile"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                         collectionDirectory <span class="token operator">+</span> <span class="token function">QLatin1String</span><span class="token punctuation">(</span><span class="token string">"/simpletextviewer.qhc"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                         <span class="token function">QLatin1String</span><span class="token punctuation">(</span><span class="token string">"-enableRemoteControl"</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

        m_process<span class="token operator">-></span><span class="token function">start</span><span class="token punctuation">(</span>app<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//bool QProcess::waitForStarted(int msecs = 30000)</span>
        <span class="token comment">//阻塞直到进程启动并发出了开始()信号,或者直到 msecs 毫秒已经过去。</span>
        <span class="token comment">//如果进程启动成功则返回真; 否则返回 false(如果操作超时或发生错误)。</span>
        <span class="token comment">//这个函数可以在没有事件循环的情况下运行。 在编写非 GUI 应用程序和在非 GUI 线程中执行 I/O 操作时,它很有用。        </span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>m_process<span class="token operator">-></span><span class="token function">waitForStarted</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token function">showError</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Unable to launch Qt Assistant (%1): %2"</span><span class="token punctuation">)</span>
                              <span class="token punctuation">.</span><span class="token function">arg</span><span class="token punctuation">(</span><span class="token class-name">QDir</span><span class="token operator">::</span><span class="token function">toNativeSeparators</span><span class="token punctuation">(</span>app<span class="token punctuation">)</span><span class="token punctuation">,</span> m_process<span class="token operator">-></span><span class="token function">errorString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//! [2]</span>

<span class="token keyword">void</span> <span class="token class-name">Assistant</span><span class="token operator">::</span><span class="token function">showError</span><span class="token punctuation">(</span><span class="token keyword">const</span> QString <span class="token operator">&</span>message<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//[static] QMessageBox::StandardButton QMessageBox::critical(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = Ok, QMessageBox::StandardButton defaultButton = NoButton)</span>
    <span class="token comment">//在指定的父小部件前面打开一个具有给定标题和文本的关键消息框。</span>
    <span class="token comment">//标准按钮被添加到消息框中。 defaultButton 指定按下 Enter 时使用的按钮。</span>
    <span class="token comment">//defaultButton 必须引用在按钮中给出的按钮。 如果 defaultButton 是 QMessageBox::NoButton,QMessageBox 会自动选择一个合适的默认值。</span>
    <span class="token class-name">QMessageBox</span><span class="token operator">::</span><span class="token function">critical</span><span class="token punctuation">(</span><span class="token class-name">QApplication</span><span class="token operator">::</span><span class="token function">activeWindow</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                          <span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Simple Text Viewer"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> message<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token class-name">Assistant</span><span class="token operator">::</span><span class="token function">finished</span><span class="token punctuation">(</span><span class="token keyword">int</span> exitCode<span class="token punctuation">,</span> QProcess<span class="token operator">::</span>ExitStatus status<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//[static] QString QString::fromLocal8Bit(const char *str, qsizetype size)</span>
    <span class="token comment">//返回用 8 位字符串 str 的第一个大小字符初始化的 QString。</span>
    <span class="token comment">//如果 size 为 -1,则使用 strlen(str) 代替。</span>
    <span class="token comment">//在 Unix 系统上,这等效于 fromUtf8(),在 Windows 上,使用的是系统当前代码页。</span>
    <span class="token comment">//QByteArray QProcess::readAllStandardError()</span>
    <span class="token comment">//无论当前的读取通道如何,此函数都会以 QByteArray 的形式返回进程标准错误中的所有可用数据。</span>
    <span class="token keyword">const</span> QString stdErr <span class="token operator">=</span> <span class="token class-name">QString</span><span class="token operator">::</span><span class="token function">fromLocal8Bit</span><span class="token punctuation">(</span>m_process<span class="token operator">-></span><span class="token function">readAllStandardError</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">!=</span> QProcess<span class="token operator">::</span>NormalExit<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">showError</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Assistant crashed: "</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">arg</span><span class="token punctuation">(</span>stdErr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>exitCode <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">showError</span><span class="token punctuation">(</span><span class="token function">tr</span><span class="token punctuation">(</span><span class="token string">"Assistant exited with %1: %2"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">arg</span><span class="token punctuation">(</span>exitCode<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">arg</span><span class="token punctuation">(</span>stdErr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1691914842761408512"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Qt,学习,Qt,qt)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1835514464028422144.htm"
                           title="情绪觉察日记第37天" target="_blank">情绪觉察日记第37天</a>
                        <span class="text-muted">露露_e800</span>

                        <div>今天是家庭关系规划师的第二阶最后一天,慧萍老师帮我做了个案,帮我处理了埋在心底好多年的一份恐惧,并给了我深深的力量!这几天出来学习,爸妈过来婆家帮我带小孩,妈妈出于爱帮我收拾东西,并跟我先生和婆婆产生矛盾,妈妈觉得他们没有照顾好我…。今晚回家见到妈妈,我很欣赏她并赞扬她,妈妈说今晚要跟我睡我说好,当我们俩躺在床上准备睡觉的时候,我握着妈妈的手对她说:妈妈这几天辛苦你了,你看你多利害把我们的家收拾得</div>
                    </li>
                    <li><a href="/article/1835513803861749760.htm"
                           title="机器学习与深度学习间关系与区别" target="_blank">机器学习与深度学习间关系与区别</a>
                        <span class="text-muted">ℒℴѵℯ心·动ꦿ໊ོ꫞</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>一、机器学习概述定义机器学习(MachineLearning,ML)是一种通过数据驱动的方法,利用统计学和计算算法来训练模型,使计算机能够从数据中学习并自动进行预测或决策。机器学习通过分析大量数据样本,识别其中的模式和规律,从而对新的数据进行判断。其核心在于通过训练过程,让模型不断优化和提升其预测准确性。主要类型1.监督学习(SupervisedLearning)监督学习是指在训练数据集中包含输入</div>
                    </li>
                    <li><a href="/article/1835513701143244800.htm"
                           title="铭刻于星(四十二)" target="_blank">铭刻于星(四十二)</a>
                        <span class="text-muted">随风至</span>

                        <div>69夜晚,绍敏同学做完功课后,看了眼房外,没听到动静才敢从书包的夹层里拿出那个心形纸团。折痕压得很深,都有些旧了,想来是已经写好很久了。绍敏同学慢慢地、轻轻地捏开折叠处,待到全部拆开后,又反复抚平纸张,然后仔细地一字字默看。只是开头的三个字是第一次看到,让她心漏跳了几拍。“亲爱的绍敏:从四年级的时候,我就喜欢你了,但是我一直不敢说,怕影响你学习。六年级的时候听说有人跟你表白,你接受了,我很难过,但</div>
                    </li>
                    <li><a href="/article/1835513424734416896.htm"
                           title="UI学习——cell的复用和自定义cell" target="_blank">UI学习——cell的复用和自定义cell</a>
                        <span class="text-muted">Magnetic_h</span>
<a class="tag" taget="_blank" href="/search/ui/1.htm">ui</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a>
                        <div>目录cell的复用手动(非注册)自动(注册)自定义cellcell的复用在iOS开发中,单元格复用是一种提高表格(UITableView)和集合视图(UICollectionView)滚动性能的技术。当一个UITableViewCell或UICollectionViewCell首次需要显示时,如果没有可复用的单元格,则视图会创建一个新的单元格。一旦这个单元格滚动出屏幕,它就不会被销毁。相反,它被添</div>
                    </li>
                    <li><a href="/article/1835511542284644352.htm"
                           title="学点心理知识,呵护孩子健康" target="_blank">学点心理知识,呵护孩子健康</a>
                        <span class="text-muted">静候花开_7090</span>

                        <div>昨天听了华中师范大学教育管理学系副教授张玲老师的《哪里才是学生心理健康的最后庇护所,超越教育与技术的思考》的讲座。今天又重新学习了一遍,收获匪浅。张玲博士也注意到了当今社会上的孩子由于心理问题导致的自残、自杀及伤害他人等恶性事件。她向我们普及了一个重要的命题,她说心理健康的一些基本命题,我们与我们通常的一些教育命题是不同的,她还举了几个例子,让我们明白我们原来以为的健康并非心理学上的健康。比如如果</div>
                    </li>
                    <li><a href="/article/1835509391361667072.htm"
                           title="Linux下QT开发的动态库界面弹出操作(SDL2)" target="_blank">Linux下QT开发的动态库界面弹出操作(SDL2)</a>
                        <span class="text-muted">13jjyao</span>
<a class="tag" taget="_blank" href="/search/QT%E7%B1%BB/1.htm">QT类</a><a class="tag" taget="_blank" href="/search/qt/1.htm">qt</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/sdl2/1.htm">sdl2</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>需求:操作系统为linux,开发框架为qt,做成需带界面的qt动态库,调用方为java等非qt程序难点:调用方为java等非qt程序,也就是说调用方肯定不带QApplication::exec(),缺少了这个,QTimer等事件和QT创建的窗口将不能弹出(包括opencv也是不能弹出);这与qt调用本身qt库是有本质的区别的思路:1.调用方缺QApplication::exec(),那么我们在接口</div>
                    </li>
                    <li><a href="/article/1835508131032035328.htm"
                           title="ArcGIS栅格计算器常见公式(赋值、0和空值的转换、补充栅格空值)" target="_blank">ArcGIS栅格计算器常见公式(赋值、0和空值的转换、补充栅格空值)</a>
                        <span class="text-muted">研学随笔</span>
<a class="tag" taget="_blank" href="/search/arcgis/1.htm">arcgis</a><a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a>
                        <div>我们在使用ArcGIS时通常经常用到栅格计算器,今天主要给大家介绍我日常中经常用到的几个公式,供大家参考学习。将特定值(-9999)赋值为0,例如-9999.Con("raster"==-9999,0,"raster")2.给空值赋予特定的值(如0)Con(IsNull("raster"),0,"raster")3.将特定的栅格值(如1)赋值为空值,其他保留原值SetNull("raster"==</div>
                    </li>
                    <li><a href="/article/1835507248395284480.htm"
                           title="【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数" target="_blank">【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数</a>
                        <span class="text-muted">广龙宇</span>
<a class="tag" taget="_blank" href="/search/%E4%B8%80%E8%B5%B7%E5%AD%A6Rust/1.htm">一起学Rust</a><a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Rust%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">Rust设计模式</a><a class="tag" taget="_blank" href="/search/rust/1.htm">rust</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、使用借用类型作为参数二、格式化拼接字符串三、使用构造函数总结前言Rust不是传统的面向对象编程语言,它的所有特性,使其独一无二。因此,学习特定于Rust的设计模式是必要的。本系列文章为作者学习《Rust设计模式》的学习笔记以及自己的见解。因此,本系列文章的结构也与此书的结构相同(后续可能会调成结构),基本上分为三个部分</div>
                    </li>
                    <li><a href="/article/1835506996258893824.htm"
                           title="回溯 Leetcode 332 重新安排行程" target="_blank">回溯 Leetcode 332 重新安排行程</a>
                        <span class="text-muted">mmaerd</span>
<a class="tag" taget="_blank" href="/search/Leetcode%E5%88%B7%E9%A2%98%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/1.htm">Leetcode刷题学习记录</a><a class="tag" taget="_blank" href="/search/leetcode/1.htm">leetcode</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E8%81%8C%E5%9C%BA%E5%92%8C%E5%8F%91%E5%B1%95/1.htm">职场和发展</a>
                        <div>重新安排行程Leetcode332学习记录自代码随想录给你一份航线列表tickets,其中tickets[i]=[fromi,toi]表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。所有这些机票都属于一个从JFK(肯尼迪国际机场)出发的先生,所以该行程必须从JFK开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。例如,行程[“JFK”,“LGA”]与[“JFK”,“LGB</div>
                    </li>
                    <li><a href="/article/1835506869838376960.htm"
                           title="Python数据分析与可视化实战指南" target="_blank">Python数据分析与可视化实战指南</a>
                        <span class="text-muted">William数据分析</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE/1.htm">数据</a>
                        <div>在数据驱动的时代,Python因其简洁的语法、强大的库生态系统以及活跃的社区,成为了数据分析与可视化的首选语言。本文将通过一个详细的案例,带领大家学习如何使用Python进行数据分析,并通过可视化来直观呈现分析结果。一、环境准备1.1安装必要库在开始数据分析和可视化之前,我们需要安装一些常用的库。主要包括pandas、numpy、matplotlib和seaborn等。这些库分别用于数据处理、数学</div>
                    </li>
                    <li><a href="/article/1835504817905168384.htm"
                           title="2019-12-22-22:30" target="_blank">2019-12-22-22:30</a>
                        <span class="text-muted">涓涓1016</span>

                        <div>今天是冬至,写下我的日更,是因为这两天的学习真的是能量的满满,让我看到了自己,未来另外一种可能性,也让我看到了这两年这几年的过程中我所接受那些痛苦的来源。一切的根源和痛苦都来自于人生,家庭,而你的原生家庭,你的爸爸和妈妈,是因为你这个灵魂在那一刻选择他们作为你的爸爸和妈妈来的,所以你得接受他,你得接纳他,他就是因为他的存在而给你的学习和成长带来这些痛苦,那其实是你必然要经历的这个过程,当你去接纳的</div>
                    </li>
                    <li><a href="/article/1835503965563875328.htm"
                           title="python os.environ_python os.environ 读取和设置环境变量" target="_blank">python os.environ_python os.environ 读取和设置环境变量</a>
                        <span class="text-muted">weixin_39605414</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/os.environ/1.htm">os.environ</a>
                        <div>>>>importos>>>os.environ.keys()['LC_NUMERIC','GOPATH','GOROOT','GOBIN','LESSOPEN','SSH_CLIENT','LOGNAME','USER','HOME','LC_PAPER','PATH','DISPLAY','LANG','TERM','SHELL','J2REDIR','LC_MONETARY','QT_QPA</div>
                    </li>
                    <li><a href="/article/1835502704827396096.htm"
                           title="将cmd中命令输出保存为txt文本文件" target="_blank">将cmd中命令输出保存为txt文本文件</a>
                        <span class="text-muted">落难Coder</span>
<a class="tag" taget="_blank" href="/search/Windows/1.htm">Windows</a><a class="tag" taget="_blank" href="/search/cmd/1.htm">cmd</a><a class="tag" taget="_blank" href="/search/window/1.htm">window</a>
                        <div>最近深度学习本地的训练中我们常常要在命令行中运行自己的代码,无可厚非,我们有必要保存我们的炼丹结果,但是复制命令行输出到txt是非常麻烦的,其实Windows下的命令行为我们提供了相应的操作。其基本的调用格式就是:运行指令>输出到的文件名称或者具体保存路径测试下,我打开cmd并且ping一下百度:pingwww.baidu.com>./data.txt看下相同目录下data.txt的输出:如果你再</div>
                    </li>
                    <li><a href="/article/1835499615491813376.htm"
                           title="四章-32-点要素的聚合" target="_blank">四章-32-点要素的聚合</a>
                        <span class="text-muted">彩云飘过</span>

                        <div>本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters.</div>
                    </li>
                    <li><a href="/article/1835496402042580992.htm"
                           title="GitHub上克隆项目" target="_blank">GitHub上克隆项目</a>
                        <span class="text-muted">bigbig猩猩</span>
<a class="tag" taget="_blank" href="/search/github/1.htm">github</a>
                        <div>从GitHub上克隆项目是一个简单且直接的过程,它允许你将远程仓库中的项目复制到你的本地计算机上,以便进行进一步的开发、测试或学习。以下是一个详细的步骤指南,帮助你从GitHub上克隆项目。一、准备工作1.安装Git在克隆GitHub项目之前,你需要在你的计算机上安装Git工具。Git是一个开源的分布式版本控制系统,用于跟踪和管理代码变更。你可以从Git的官方网站(https://git-scm.</div>
                    </li>
                    <li><a href="/article/1835496148601761792.htm"
                           title="HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动" target="_blank">HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动</a>
                        <span class="text-muted">二挡起步</span>
<a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/web%E8%AE%BE%E8%AE%A1%E7%BD%91%E9%A1%B5%E8%A7%84%E5%88%92%E4%B8%8E%E8%AE%BE%E8%AE%A1/1.htm">web设计网页规划与设计</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/dreamweaver/1.htm">dreamweaver</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                        <div>Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线</div>
                    </li>
                    <li><a href="/article/1835495644123459584.htm"
                           title="Day1笔记-Python简介&标识符和关键字&输入输出" target="_blank">Day1笔记-Python简介&标识符和关键字&输入输出</a>
                        <span class="text-muted">~在杰难逃~</span>
<a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a>
                        <div>大家好,从今天开始呢,杰哥开展一个新的专栏,当然,数据分析部分也会不定时更新的,这个新的专栏主要是讲解一些Python的基础语法和知识,帮助0基础的小伙伴入门和学习Python,感兴趣的小伙伴可以开始认真学习啦!一、Python简介【了解】1.计算机工作原理编程语言就是用来定义计算机程序的形式语言。我们通过编程语言来编写程序代码,再通过语言处理程序执行向计算机发送指令,让计算机完成对应的工作,编程</div>
                    </li>
                    <li><a href="/article/1835494131535802368.htm"
                           title="人工智能时代,程序员如何保持核心竞争力?" target="_blank">人工智能时代,程序员如何保持核心竞争力?</a>
                        <span class="text-muted">jmoych</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a>
                        <div>随着AIGC(如chatgpt、midjourney、claude等)大语言模型接二连三的涌现,AI辅助编程工具日益普及,程序员的工作方式正在发生深刻变革。有人担心AI可能取代部分编程工作,也有人认为AI是提高效率的得力助手。面对这一趋势,程序员应该如何应对?是专注于某个领域深耕细作,还是广泛学习以适应快速变化的技术环境?又或者,我们是否应该将重点转向AI无法轻易替代的软技能?让我们一起探讨程序员</div>
                    </li>
                    <li><a href="/article/1835492740536823808.htm"
                           title="node.js学习" target="_blank">node.js学习</a>
                        <span class="text-muted">小猿L</span>
<a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/vim/1.htm">vim</a>
                        <div>node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行</div>
                    </li>
                    <li><a href="/article/1835492372952215552.htm"
                           title="阶段总结反思" target="_blank">阶段总结反思</a>
                        <span class="text-muted">轻争</span>

                        <div>马上就要进入10月份了,今天做一下前段时间的总结和反思。前段时间,日更、英语、健身、护肤坚持的比较好。阅读、书法坚持的不好。1.中间被迫停更半个多月,其余时间一直在坚持日更挑战。偶尔也有不想写的时候,就做一下摘抄。因为阅读(输入)没跟上来,所以写作(输出)质量有待进一步加强。2.英语做到了一周至少学习5天,每次不少于30分钟,但是小班课没有跟上更新速度,下一步要争取利用零碎时间补听小班课。3.减肥</div>
                    </li>
                    <li><a href="/article/1835489587498151936.htm"
                           title="ARM驱动学习之基础小知识" target="_blank">ARM驱动学习之基础小知识</a>
                        <span class="text-muted">JT灬新一</span>
<a class="tag" taget="_blank" href="/search/ARM/1.htm">ARM</a><a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%85%A5%E5%BC%8F/1.htm">嵌入式</a><a class="tag" taget="_blank" href="/search/arm%E5%BC%80%E5%8F%91/1.htm">arm开发</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a>
                        <div>ARM驱动学习之基础小知识•sch原理图工程师工作内容–方案–元器件选型–采购(能不能买到,价格)–原理图(涉及到稳定性)•layout画板工程师–layout(封装、布局,布线,log)(涉及到稳定性)–焊接的一部分工作(调试阶段板子的焊接)•驱动工程师–驱动,原理图,layout三部分的交集容易发生矛盾•PCB研发流程介绍–方案,原理图(网表)–layout工程师(gerber文件)–PCB板</div>
                    </li>
                    <li><a href="/article/1835489588169240576.htm"
                           title="ARM驱动学习之5 LEDS驱动" target="_blank">ARM驱动学习之5 LEDS驱动</a>
                        <span class="text-muted">JT灬新一</span>
<a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%85%A5%E5%BC%8F/1.htm">嵌入式</a><a class="tag" taget="_blank" href="/search/C/1.htm">C</a><a class="tag" taget="_blank" href="/search/%E5%BA%95%E5%B1%82/1.htm">底层</a><a class="tag" taget="_blank" href="/search/arm%E5%BC%80%E5%8F%91/1.htm">arm开发</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E5%8D%95%E7%89%87%E6%9C%BA/1.htm">单片机</a>
                        <div>ARM驱动学习之5LEDS驱动知识点:•linuxGPIO申请函数和赋值函数–gpio_request–gpio_set_value•三星平台配置GPIO函数–s3c_gpio_cfgpin•GPIO配置输出模式的宏变量–S3C_GPIO_OUTPUT注意点:DRIVER_NAME和DEVICE_NAME匹配。实现步骤:1.加入需要的头文件://Linux平台的gpio头文件#include//三</div>
                    </li>
                    <li><a href="/article/1835489586684456960.htm"
                           title="ARM驱动学习之4小结" target="_blank">ARM驱动学习之4小结</a>
                        <span class="text-muted">JT灬新一</span>
<a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%85%A5%E5%BC%8F/1.htm">嵌入式</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/arm%E5%BC%80%E5%8F%91/1.htm">arm开发</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>ARM驱动学习之4小结#include#include#include#include#include#defineDEVICE_NAME"hello_ctl123"MODULE_LICENSE("DualBSD/GPL");MODULE_AUTHOR("TOPEET");staticlonghello_ioctl(structfile*file,unsignedintcmd,unsignedlo</div>
                    </li>
                    <li><a href="/article/1835489566702792704.htm"
                           title="展现思维导图魅力,不断挖掘人生宝藏" target="_blank">展现思维导图魅力,不断挖掘人生宝藏</a>
                        <span class="text-muted">思维导图讲师Mandy</span>

                        <div>第13期最强思维导图训练营已经结束一周了,但是我依旧是感觉所有学员还在努力的学习,这些学员中有教师、学生、白领、公务员、宝妈等等,只要你努力,只要你想改变自己,任何行业,任何岗位都可以参与进来,28天足以让你见成效,在这28天中,我们的学员不仅仅是收获了一枚毕业证,最重要的是让自己的思维方式得到升级,今天的你为自己投资,明天的你就会感谢你今天的付出,我们来听一听来自13期最强思维导图训练营优秀学员</div>
                    </li>
                    <li><a href="/article/1835488930972135424.htm"
                           title="2019-3-23晨间日记" target="_blank">2019-3-23晨间日记</a>
                        <span class="text-muted">红红火火小耳朵</span>

                        <div>今天是什么日子起床:7点40就寝:23点半天气:有太阳,不过一会儿出来一会儿进去特别清爽的凉意,还蛮舒服的心情:小激动要给女朋友过生日啦纪念日:田田女士过生日任务清单昨日完成的任务,最重要的三件事:1.英语一对一2.运动计划3.认真护肤习惯养成:调整状态周目标·完成进度英语七天打卡(5/7)轻课阅读(87/180)音标课(25/30)读书(福尔摩斯一章)学习·信息·阅读#英语课#Cookingte</div>
                    </li>
                    <li><a href="/article/1835485681187647488.htm"
                           title="【华为OD技术面试真题精选 - 非技术题】 -HR面,综合面_华为od hr面" target="_blank">【华为OD技术面试真题精选 - 非技术题】 -HR面,综合面_华为od hr面</a>
                        <span class="text-muted">一个射手座的程序媛</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BAod/1.htm">华为od</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E8%81%8C%E5%9C%BA%E5%92%8C%E5%8F%91%E5%B1%95/1.htm">职场和发展</a>
                        <div>最后的话最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!资料预览给大家整理的视频资料:给大家整理的电子书资料:如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以点击这里获</div>
                    </li>
                    <li><a href="/article/1835483983241113600.htm"
                           title="教育" target="_blank">教育</a>
                        <span class="text-muted">用心灵温暖心灵</span>

                        <div>@陈春丽长期学习班冯倩。今天一早就听到说高职合并,取消中专教育的教育信息。感觉是虽然知道,再听还是吓一跳。国家重视职业教育为何还要取消中专技术学校的教育?再听高中就要进行技术教育了,一部分人学习好继续努力学习考大学,一部分人在高中就可以进行职业教育接受职业教育了还要中专技术教育学校干什么呢!a有些职业教育学校转型升级快,不是孩子上完给找工作,而是学校帮孩子创业,我觉得是不错的方向!新闻新你得实时更</div>
                    </li>
                    <li><a href="/article/1835483730358136832.htm"
                           title="数字里的世界17期:2021年全球10大顶级数据中心,中国移动榜首" target="_blank">数字里的世界17期:2021年全球10大顶级数据中心,中国移动榜首</a>
                        <span class="text-muted">张三叨</span>

                        <div>你知道吗?2016年,全球的数据中心共计用电4160亿千瓦时,比整个英国的发电量还多40%!前言每天,我们都会创造超过250万TB的数据。并且随着物联网(IOT)的不断普及,这一数据将持续增长。如此庞大的数据被存储在被称为“数据中心”的专用设施中。虽然最早的数据中心建于20世纪40年代,但直到1997-2000年的互联网泡沫期间才逐渐成为主流。当前人类的技术,比如人工智能和机器学习,已经将我们推向</div>
                    </li>
                    <li><a href="/article/1835483474883080192.htm"
                           title="学习“论语”-第59天" target="_blank">学习“论语”-第59天</a>
                        <span class="text-muted">春峰轩</span>

                        <div>12.14子张问政。子曰:“居之无倦,行之以忠。”子张问为政之道。孔子说:“在位尽职不懈怠,执行政令要忠诚。”12.15子曰:“博学于文,约之以礼,亦可以弗畔矣夫!”孔子说:“君子广泛地学习文献,并且用礼节约束自己,也就不会离经叛道了。”12.16子曰:“君子成人之美,不成人之恶。小人反是。”孔子说:“君子成全别人的好事,而不助长别人的坏处。小人则与此相反行事。”知识点:“成人之美,不成人之恶”贯</div>
                    </li>
                    <li><a href="/article/1835483159630802944.htm"
                           title="nosql数据库技术与应用知识点" target="_blank">nosql数据库技术与应用知识点</a>
                        <span class="text-muted">皆过客,揽星河</span>
<a class="tag" taget="_blank" href="/search/NoSQL/1.htm">NoSQL</a><a class="tag" taget="_blank" href="/search/nosql/1.htm">nosql</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/%E9%9D%9E%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">非关系型数据库</a>
                        <div>Nosql知识回顾大数据处理流程数据采集(flume、爬虫、传感器)数据存储(本门课程NoSQL所处的阶段)Hdfs、MongoDB、HBase等数据清洗(入仓)Hive等数据处理、分析(Spark、Flink等)数据可视化数据挖掘、机器学习应用(Python、SparkMLlib等)大数据时代存储的挑战(三高)高并发(同一时间很多人访问)高扩展(要求随时根据需求扩展存储)高效率(要求读写速度快)</div>
                    </li>
                                <li><a href="/article/11.htm"
                                       title="VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite" target="_blank">VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite</a>
                                    <span class="text-muted">iwindyforest</span>
<a class="tag" taget="_blank" href="/search/vmware/1.htm">vmware</a><a class="tag" taget="_blank" href="/search/mac+os/1.htm">mac os</a><a class="tag" taget="_blank" href="/search/10.10/1.htm">10.10</a><a class="tag" taget="_blank" href="/search/workstation/1.htm">workstation</a><a class="tag" taget="_blank" href="/search/player/1.htm">player</a>
                                    <div>最近尝试了下VMware下安装MacOS 系统, 
安装过程中发现网上可供参考的文章都是VMware Workstation 10以下, MacOS X 10.9以下的文章, 
只能提供大概的思路, 但是实际安装起来由于版本问题, 走了不少弯路, 所以我尝试写以下总结, 希望能给有兴趣安装OSX的人提供一点帮助。 
  
  
写在前面的话: 
其实安装好后发现, 由于我的th</div>
                                </li>
                                <li><a href="/article/138.htm"
                                       title="关于《基于模型驱动的B/S在线开发平台》源代码开源的疑虑?" target="_blank">关于《基于模型驱动的B/S在线开发平台》源代码开源的疑虑?</a>
                                    <span class="text-muted">deathwknight</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%A1%86%E6%9E%B6/1.htm">框架</a>
                                    <div>本人从学习Java开发到现在已有10年整,从一个要自学 java买成javascript的小菜鸟,成长为只会java和javascript语言的老菜鸟(个人邮箱:deathwknight@163.com) 
 
一路走来,跌跌撞撞。用自己的三年多业余时间,瞎搞一个小东西(基于模型驱动的B/S在线开发平台,非MVC框架、非代码生成)。希望与大家一起分享,同时有许些疑虑,希望有人可以交流下 
 
平台</div>
                                </li>
                                <li><a href="/article/265.htm"
                                       title="如何把maven项目转成web项目" target="_blank">如何把maven项目转成web项目</a>
                                    <span class="text-muted">Kai_Ge</span>
<a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a><a class="tag" taget="_blank" href="/search/MyEclipse/1.htm">MyEclipse</a>
                                    <div>创建Web工程,使用eclipse ee创建maven web工程 1.右键项目,选择Project Facets,点击Convert to faceted from 2.更改Dynamic Web Module的Version为2.5.(3.0为Java7的,Tomcat6不支持). 如果提示错误,可能需要在Java Compiler设置Compiler compl</div>
                                </li>
                                <li><a href="/article/392.htm"
                                       title="主管???" target="_blank">主管???</a>
                                    <span class="text-muted">Array_06</span>
<a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a>
                                    <div>转载:http://www.blogjava.net/fastzch/archive/2010/11/25/339054.html 
 
 
 
 
很久以前跟同事参加的培训,同事整理得很详细,必须得转! 
 
前段时间,公司有组织中高阶主管及其培养干部进行了为期三天的管理训练培训。三天的课程下来,虽然内容较多,因对老师三天来的课程内容深有感触,故借着整理学习心得的机会,将三天来的培训课程做了一个</div>
                                </li>
                                <li><a href="/article/519.htm"
                                       title="python内置函数大全" target="_blank">python内置函数大全</a>
                                    <span class="text-muted">2002wmj</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                                    <div>最近一直在看python的document,打算在基础方面重点看一下python的keyword、Build-in Function、Build-in Constants、Build-in Types、Build-in Exception这四个方面,其实在看的时候发现整个《The Python Standard Library》章节都是很不错的,其中描述了很多不错的主题。先把Build-in Fu</div>
                                </li>
                                <li><a href="/article/646.htm"
                                       title="JSP页面通过JQUERY合并行" target="_blank">JSP页面通过JQUERY合并行</a>
                                    <span class="text-muted">357029540</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a>
                                    <div>在写程序的过程中我们难免会遇到在页面上合并单元行的情况,如图所示 
 
 
如果对于会的同学可能很简单,但是对没有思路的同学来说还是比较麻烦的,提供一下用JQUERY实现的参考代码 
 
function mergeCell(){ 
        var trs = $("#table tr"); 
&nb</div>
                                </li>
                                <li><a href="/article/773.htm"
                                       title="Java基础" target="_blank">Java基础</a>
                                    <span class="text-muted">冰天百华</span>
<a class="tag" taget="_blank" href="/search/java%E5%9F%BA%E7%A1%80/1.htm">java基础</a>
                                    <div>学习函数式编程 
package base;

import java.text.DecimalFormat;

public class Main {

	public static void main(String[] args) {
//		Integer a = 4;  
//		Double aa = (double)a  / 100000;  
//		Decimal</div>
                                </li>
                                <li><a href="/article/900.htm"
                                       title="unix时间戳相互转换" target="_blank">unix时间戳相互转换</a>
                                    <span class="text-muted">adminjun</span>
<a class="tag" taget="_blank" href="/search/%E8%BD%AC%E6%8D%A2/1.htm">转换</a><a class="tag" taget="_blank" href="/search/unix/1.htm">unix</a><a class="tag" taget="_blank" href="/search/%E6%97%B6%E9%97%B4%E6%88%B3/1.htm">时间戳</a>
                                    <div>如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)?     Java time   JavaScript Math.round(new Date().getTime()/1000)
getTime()返回数值的单位是毫秒   Microsoft .NET / C# epoch = (DateTime.Now.ToUniversalTime().Ticks - 62135</div>
                                </li>
                                <li><a href="/article/1027.htm"
                                       title="作为一个合格程序员该做的事" target="_blank">作为一个合格程序员该做的事</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a>
                                    <div>作为一个合格程序员每天该做的事   1、总结自己一天任务的完成情况 最好的方式是写工作日志,把自己今天完成了什么事情,遇见了什么问题都记录下来,日后翻看好处多多 
2、考虑自己明天应该做的主要工作 把明天要做的事情列出来,并按照优先级排列,第二天应该把自己效率最高的时间分配给最重要的工作 
3、考虑自己一天工作中失误的地方,并想出避免下一次再犯的方法 出错不要紧,最重</div>
                                </li>
                                <li><a href="/article/1154.htm"
                                       title="由html5视频播放引发的总结" target="_blank">由html5视频播放引发的总结</a>
                                    <span class="text-muted">ayaoxinchao</span>
<a class="tag" taget="_blank" href="/search/html5/1.htm">html5</a><a class="tag" taget="_blank" href="/search/%E8%A7%86%E9%A2%91/1.htm">视频</a><a class="tag" taget="_blank" href="/search/video/1.htm">video</a>
                                    <div>前言 
  
项目中存在视频播放的功能,前期设计是以flash播放器播放视频的。但是现在由于需要兼容苹果的设备,必须采用html5的方式来播放视频。我就出于兴趣对html5播放视频做了简单的了解,不了解不知道,水真是很深。本文所记录的知识一些浅尝辄止的知识,说起来很惭愧。 
  
视频结构 
  
本该直接介绍html5的<video>的,但鉴于本人对视频</div>
                                </li>
                                <li><a href="/article/1281.htm"
                                       title="解决httpclient访问自签名https报javax.net.ssl.SSLHandshakeException: sun.security.validat" target="_blank">解决httpclient访问自签名https报javax.net.ssl.SSLHandshakeException: sun.security.validat</a>
                                    <span class="text-muted">bewithme</span>
<a class="tag" taget="_blank" href="/search/httpclient/1.htm">httpclient</a>
                                    <div>     如果你构建了一个https协议的站点,而此站点的安全证书并不是合法的第三方证书颁发机构所签发,那么你用httpclient去访问此站点会报如下错误 
  
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path bu</div>
                                </li>
                                <li><a href="/article/1408.htm"
                                       title="Jedis连接池的入门级使用" target="_blank">Jedis连接池的入门级使用</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/redis%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">redis数据库</a><a class="tag" taget="_blank" href="/search/jedis/1.htm">jedis</a>
                                    <div>Jedis连接池操作步骤如下: 
        a.获取Jedis实例需要从JedisPool中获取; 
        b.用完Jedis实例需要返还给JedisPool; 
        c.如果Jedis在使用过程中出错,则也需要还给JedisPool; 
packag</div>
                                </li>
                                <li><a href="/article/1535.htm"
                                       title="变与不变" target="_blank">变与不变</a>
                                    <span class="text-muted">bingyingao</span>
<a class="tag" taget="_blank" href="/search/%E4%B8%8D%E5%8F%98/1.htm">不变</a><a class="tag" taget="_blank" href="/search/%E5%8F%98/1.htm">变</a><a class="tag" taget="_blank" href="/search/%E4%BA%B2%E6%83%85%E6%B0%B8%E6%81%92/1.htm">亲情永恒</a>
                                    <div>变与不变 
   周末骑车转到了五年前租住的小区,曾经最爱吃的西北面馆、江西水饺、手工拉面早已不在, 
   各种店铺都换了好几茬,这些是变的。 
   三年前还很流行的一款手机在今天看起来已经落后的不像样子。 
   三年前还运行的好好的一家公司,今天也已经不复存在。 
   一座座高楼拔地而起,</div>
                                </li>
                                <li><a href="/article/1662.htm"
                                       title="【Scala十】Scala核心四:集合框架之List" target="_blank">【Scala十】Scala核心四:集合框架之List</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a>
                                    <div>Spark的RDD作为一个分布式不可变的数据集合,它提供的转换操作,很多是借鉴于Scala的集合框架提供的一些函数,因此,有必要对Scala的集合进行详细的了解 
  
1. 泛型集合都是协变的,对于List而言,如果B是A的子类,那么List[B]也是List[A]的子类,即可以把List[B]的实例赋值给List[A]变量 
  
2. 给变量赋值(注意val关键字,a,b</div>
                                </li>
                                <li><a href="/article/1789.htm"
                                       title="Nested Functions in C" target="_blank">Nested Functions in C</a>
                                    <span class="text-muted">bookjovi</span>
<a class="tag" taget="_blank" href="/search/c/1.htm">c</a><a class="tag" taget="_blank" href="/search/closure/1.htm">closure</a>
                                    <div>  
Nested Functions 又称closure,属于functional language中的概念,一直以为C中是不支持closure的,现在看来我错了,不过C标准中是不支持的,而GCC支持。 
  
既然GCC支持了closure,那么 lexical scoping自然也支持了,同时在C中label也是可以在nested functions中自由跳转的</div>
                                </li>
                                <li><a href="/article/1916.htm"
                                       title="Java-Collections Framework学习与总结-WeakHashMap" target="_blank">Java-Collections Framework学习与总结-WeakHashMap</a>
                                    <span class="text-muted">BrokenDreams</span>
<a class="tag" taget="_blank" href="/search/Collections/1.htm">Collections</a>
                                    <div>        总结这个类之前,首先看一下Java引用的相关知识。Java的引用分为四种:强引用、软引用、弱引用和虚引用。 
 
        
强引用:就是常见的代码中的引用,如Object o = new Object();存在强引用的对象不会被垃圾收集</div>
                                </li>
                                <li><a href="/article/2043.htm"
                                       title="读《研磨设计模式》-代码笔记-解释器模式-Interpret" target="_blank">读《研磨设计模式》-代码笔记-解释器模式-Interpret</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a>
                                    <div>声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/ 
 
 

package design.pattern;

/*
 * 解释器(Interpreter)模式的意图是可以按照自己定义的组合规则集合来组合可执行对象
 * 
 * 代码示例实现XML里面1.读取单个元素的值 2.读取单个属性的值
 * 多</div>
                                </li>
                                <li><a href="/article/2170.htm"
                                       title="After Effects操作&快捷键" target="_blank">After Effects操作&快捷键</a>
                                    <span class="text-muted">cherishLC</span>
<a class="tag" taget="_blank" href="/search/After+Effects/1.htm">After Effects</a>
                                    <div>1、快捷键官方文档 
 
 
 中文版:https://helpx.adobe.com/cn/after-effects/using/keyboard-shortcuts-reference.html  
 英文版:https://helpx.adobe.com/after-effects/using/keyboard-shortcuts-reference.html  
 
 
 2、常用快捷键</div>
                                </li>
                                <li><a href="/article/2297.htm"
                                       title="Maven 常用命令" target="_blank">Maven 常用命令</a>
                                    <span class="text-muted">crabdave</span>
<a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a>
                                    <div>Maven 常用命令 
  
mvn archetype:generate 
mvn install 
mvn clean 
mvn clean complie 
mvn clean test 
mvn clean install 
mvn clean package 
mvn test 
mvn package 
mvn site 
  
mvn dependency:res</div>
                                </li>
                                <li><a href="/article/2424.htm"
                                       title="shell bad substitution" target="_blank">shell bad substitution</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a><a class="tag" taget="_blank" href="/search/%E8%84%9A%E6%9C%AC/1.htm">脚本</a>
                                    <div>#!/bin/sh 
 
/data/script/common/run_cmd.exp 192.168.13.168 "impala-shell -islave4 -q 'insert OVERWRITE table imeis.${tableName} select ${selectFields}, ds, fnv_hash(concat(cast(ds as string), im</div>
                                </li>
                                <li><a href="/article/2551.htm"
                                       title="Java SE 第二讲(原生数据类型 Primitive Data Type)" target="_blank">Java SE 第二讲(原生数据类型 Primitive Data Type)</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>Java SE  第二讲: 
 
1.   Windows: notepad, editplus, ultraedit, gvim 
Linux: vi, vim, gedit 
 
2.   Java 中的数据类型分为两大类: 
1)原生数据类型  (Primitive Data Type) 
2)引用类型(对象类型)  (R</div>
                                </li>
                                <li><a href="/article/2678.htm"
                                       title="CGridView中实现批量删除" target="_blank">CGridView中实现批量删除</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/yii/1.htm">yii</a>
                                    <div>1,CGridView中的columns添加 
array(
                        'selectableRows' => 2,
                        'footer' => '<button type="button" onclick="GetCheckbox();" style=&</div>
                                </li>
                                <li><a href="/article/2805.htm"
                                       title="Java中泛型的各种使用" target="_blank">Java中泛型的各种使用</a>
                                    <span class="text-muted">dyy_gusi</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%B3%9B%E5%9E%8B/1.htm">泛型</a>
                                    <div>Java中的泛型的使用:1.普通的泛型使用 
在使用类的时候后面的<>中的类型就是我们确定的类型。 
public class MyClass1<T> {//此处定义的泛型是T
    private T var;

    public T getVar() {
        return var;
    }

    public void setVa</div>
                                </li>
                                <li><a href="/article/2932.htm"
                                       title="Web开发技术十年发展历程" target="_blank">Web开发技术十年发展历程</a>
                                    <span class="text-muted">gcq511120594</span>
<a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/%E6%B5%8F%E8%A7%88%E5%99%A8/1.htm">浏览器</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a>
                                    <div>回顾web开发技术这十年发展历程: 
Ajax 
03年的时候我上六年级,那时候网吧刚在小县城的角落萌生。传奇,大话西游第一代网游一时风靡。我抱着试一试的心态给了网吧老板两块钱想申请个号玩玩,然后接下来的一个小时我一直在,注,册,账,号。 
彼时网吧用的512k的带宽,注册的时候,填了一堆信息,提交,页面跳转,嘣,”您填写的信息有误,请重填”。然后跳转回注册页面,以此循环。我现在时常想,如果当时a</div>
                                </li>
                                <li><a href="/article/3059.htm"
                                       title="openSession()与getCurrentSession()区别:" target="_blank">openSession()与getCurrentSession()区别:</a>
                                    <span class="text-muted">hetongfei</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a><a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a>
                                    <div>来自 http://blog.csdn.net/dy511/article/details/6166134 
1.getCurrentSession创建的session会和绑定到当前线程,而openSession不会。 
2. getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭。 
这里getCurrentSession本地事务(本地</div>
                                </li>
                                <li><a href="/article/3186.htm"
                                       title="第一章 安装Nginx+Lua开发环境" target="_blank">第一章 安装Nginx+Lua开发环境</a>
                                    <span class="text-muted">jinnianshilongnian</span>
<a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/lua/1.htm">lua</a><a class="tag" taget="_blank" href="/search/openresty/1.htm">openresty</a>
                                    <div>首先我们选择使用OpenResty,其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。而且OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒</div>
                                </li>
                                <li><a href="/article/3313.htm"
                                       title="HSQLDB In-Process方式访问内存数据库" target="_blank">HSQLDB In-Process方式访问内存数据库</a>
                                    <span class="text-muted">liyonghui160com</span>

                                    <div>  
  
HSQLDB一大特色就是能够在内存中建立数据库,当然它也能将这些内存数据库保存到文件中以便实现真正的持久化。 
  
先睹为快! 
  
下面是一个In-Process方式访问内存数据库的代码示例: 
  
  
下面代码需要引入hsqldb.jar包 (hsqldb-2.2.8) 
  
import java.s</div>
                                </li>
                                <li><a href="/article/3440.htm"
                                       title="Java线程的5个使用技巧" target="_blank">Java线程的5个使用技巧</a>
                                    <span class="text-muted">pda158</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a>
                                    <div>Java线程有哪些不太为人所知的技巧与用法?     萝卜白菜各有所爱。像我就喜欢Java。学无止境,这也是我喜欢它的一个原因。日常 
工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是一些有趣的用法。比如说线程。没错,就是线程。或者确切说是Thread这个类。当我们在构建高可扩展性系统的时候,通常会面临各种各样的并发编程的问题,不过我们现在所要讲的可能会略有不同。   </div>
                                </li>
                                <li><a href="/article/3567.htm"
                                       title="开发资源大整合:编程语言篇——JavaScript(1)" target="_blank">开发资源大整合:编程语言篇——JavaScript(1)</a>
                                    <span class="text-muted">shoothao</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div>概述:本系列的资源整合来自于github中各个领域的大牛,来收藏你感兴趣的东西吧。           
  程序包管理器  
  管理javascript库并提供对这些库的快速使用与打包的服务。 
 
  Bower - 用于web的程序包管理。 
  component - 用于客户端的程序包管理,构建更好的web应用程序。 
  spm - 全新的静态的文件包管</div>
                                </li>
                                <li><a href="/article/3694.htm"
                                       title="避免使用终结函数" target="_blank">避免使用终结函数</a>
                                    <span class="text-muted">vahoa.ma</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a>
                                    <div>终结函数(finalizer)通常是不可预测的,常常也是很危险的,一般情况下不是必要的。使用终结函数会导致不稳定的行为、更差的性能,以及带来移植性问题。不要把终结函数当做C++中的析构函数(destructors)的对应物。 
  
    我自己总结了一下这一条的综合性结论是这样的: 
1)在涉及使用资源,使用完毕后要释放资源的情形下,首先要用一个显示的方</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>