Qt:Qt Widgets 入门编程

逃离我推掉我的手 2022-05-16 00:39 521阅读 0赞

基于记事本应用程序的Qt小部件教程。

在本主题中,我们通过使用C ++和Qt Widgets模块实现一个简单的记事本应用程序来教授基本的Qt知识。该应用程序是一个小型文本编辑器,可让您创建,保存,打印或重新打开并再次对其进行编辑的文本文件。您还可以设置要使用的字体。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaXpoZW5nZ3Vhbg_size_16_color_FFFFFF_t_70

您可以在tutorials / notepad目录的qtdoc存储库中找到最终的Notepad源文件。您可以从Qt Project获取Qt 5源,也可以将它们作为Qt 5的一部分进行安装。该应用程序也位于Qt Creator的Welcome模式的示例列表中。

创建记事本项目

在向导的帮助下,可以在Qt Creator中设置新项目,该向导将指导您逐步完成项目创建过程。向导会提示您输入该特定类型的项目所需的设置,并为您创建项目。

要创建记事本项目,请选择“文件” >“新建文件”或“项目” >Qt Widgets Application > 项目名称为Notepad > qmake > 选择QMainWindow作为基类, 类名为Notepad

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaXpoZW5nZ3Vhbg_size_16_color_FFFFFF_t_70 1

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaXpoZW5nZ3Vhbg_size_16_color_FFFFFF_t_70 2

创建出的项目目录如下:

  • notepad.pro-项目文件。
  • main.cpp-应用程序的主要源文件。
  • notepad.cpp-记事本小部件的记事本类的源文件。
  • notepad.h-记事本小部件的记事本类的头文件。
  • notepad.ui-记事本小部件的UI窗体。

20210401110938403.png

.cpp,.h和.ui文件随附了必要的样板代码,以便您能够构建和运行项目。.pro文件已完成。我们将在以下各节中仔细研究文件内容。

主要源文件

该向导在main.cpp文件中生成以下代码:

  1. #include "notepad.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication EditorApp(argc, argv);
  6. Notepad Editor;
  7. Editor.show();
  8. return EditorApp.exec();
  9. }

我们将逐行浏览代码。以下几行包括Notepad小部件和QApplication的头文件。所有Qt类都有一个以它们命名的头文件。

  1. #include "notepad.h"
  2. #include <QApplication>

下面的行定义了主要功能,它是所有基于C和C ++的应用程序的入口点:

  1. int main(int argc, char *argv[])

下一行创建一个QApplication对象。该对象管理应用程序范围的资源,对于运行任何使用Qt小部件的Qt程序是必须的。这个对象管理应用程序范围内的资源,并且是运行任何使用Qt小部件的Qt程序所必需的。它使用在argv中运行的argc命令行参数构造一个应用程序对象。(对于不使用Qt小部件的GUI应用程序,可以改用QGuiApplication。)

  1. QApplication EditorApp(argc, argv);

下一行创建记事本对象。这是向导为其创建类和UI文件的对象。用户界面包含widgets在Qt中调用的可视元素。小部件的示例包括文本编辑,滚动条,标签和单选按钮。小部件也可以是其他小部件的容器。例如对话框或主应用程序窗口。

  1. Notepad Editor;

下面一行在屏幕上自己的窗口中显示Notepad小部件。小部件还可以充当容器。这方面的一个例子是QMainWindow,它通常包含几种类型的小部件。默认情况下,小部件是不可见的;函数show()使小部件可见。

  1. Editor.show();

下一行使QApplication进入其事件循环。当Qt应用程序运行时,会生成事件(比如鼠标按下和键击)并发送到应用程序的小部件。

设计UI

向导生成XML格式的用户界面定义notepad.ui。当您在Qt Creator中打开notepad.ui文件时,它会在集成的Qt Designer中自动打开。

生成应用程序时,Qt Creator将启动Qt用户界面编译器(uic),该程序读取.ui文件并创建相应的C ++头文件ui_notepad.h。

使用Qt Designer

该向导将创建一个使用QMainWindow的应用程序。它有自己的布局,您可以添加菜单栏、停靠小部件、工具栏和状态栏。中心区域可以被任何类型的小部件占用。向导将Notepad小部件放在那里。

要在Qt Designer中添加小部件,请执行以下操作:

  1. 在Qt Creator编辑器模式下,双击“项目”视图中的notepad.ui文件,以在集成的Qt Designer中启动该文件。
  2. 将窗口小部件Text Edit(QTextEdit)拖放到窗体。
  3. Ctrl + A(或Cmd + A)选择小部件,然后单击“垂直放置”(或按Ctrl + L)以应用垂直布局(QVBoxLayout)。
  4. Ctrl + S(或Cmd + S)保存更改。

用户界面现在在Qt Designer中如下所示:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaXpoZW5nZ3Vhbg_size_16_color_FFFFFF_t_70 3

您可以在代码编辑器中查看生成的XML文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ui version="4.0">
  3. <class>Notepad</class>
  4. <widget class="QMainWindow" name="Notepad">
  5. <property name="geometry">
  6. <rect>
  7. <x>0</x>
  8. <y>0</y>
  9. <width>800</width>
  10. <height>400</height>
  11. </rect>
  12. </property>
  13. <property name="windowTitle">
  14. <string>Notepad</string>
  15. </property>
  16. <widget class="QWidget" name="centralWidget">
  17. <layout class="QVBoxLayout" name="verticalLayout">
  18. <item>
  19. <widget class="QTextEdit" name="textEdit"/>
  20. </item>
  21. </layout>
  22. </widget>
  23. <widget class="QMenuBar" name="menuBar">
  24. ...

以下行包含XML声明,该声明指定文档中使用的XML版本和字符编码:

  1. <?xml version="1.0" encoding="UTF-8"?>

文件的其余部分指定一个ui定义记事本小部件的元素:

  1. <ui version="4.0">

UI文件与Notepad类的头文件和源文件一起使用。我们将在后面的部分中查看UI文件的其余部分。

记事本头文件

该向导为Notepad类生成了一个头文件,该头文件具有必要的#include,构造函数,析构函数和Ui对象。该文件如下所示:

  1. #include <QMainWindow>
  2. namespace Ui {
  3. class Notepad;
  4. }
  5. class Notepad : public QMainWindow
  6. {
  7. Q_OBJECT
  8. public:
  9. explicit Notepad(QWidget *parent = nullptr);
  10. ~Notepad();
  11. private slots:
  12. void newDocument();
  13. void open();
  14. void save();
  15. void saveAs();
  16. void print();
  17. void exit();
  18. void copy();
  19. void cut();
  20. void paste();
  21. void undo();
  22. void redo();
  23. void selectFont();
  24. void setFontBold(bool bold);
  25. void setFontUnderline(bool underline);
  26. void setFontItalic(bool italic);
  27. void about();
  28. private:
  29. Ui::Notepad *ui;
  30. QString currentFile;
  31. };

以下行包括QMainWindow,它提供了一个主应用程序窗口:

  1. #include <QMainWindow>

以下各行在ui命名空间中声明Notepad类,该命名空间是该uic工具从生成的UI类的标准命名空间

  1. namespace Ui {
  2. class Notepad;
  3. }

类声明包含Q_OBJECT宏。它必须在类定义中排在首位,并将我们的类声明为QObject。自然,它也必须继承自QObject。QObject为普通C++类增加了一些能力。值得注意的是,类名和槽名可以在进行时查询。还可以查询槽的参数类型并调用它

  1. class Notepad : public QMainWindow
  2. {
  3. Q_OBJECT

以下几行声明了一个构造函数,该构造函数的默认参数为parent。值0表示该窗口小部件没有父窗口(它是顶部窗口小部件)

  1. public:
  2. explicit Notepad(QWidget *parent = nullptr);

下一行声明了一个虚拟析构函数,以释放对象在其生命周期中获取的资源。根据C++命名约定,析构函数与其关联的类具有相同的名称,并以波浪号(〜)为前缀。在QObject中,析构函数是虚拟的,以确保当通过指向基类的指针删除对象时,派生类的析构函数被正确调用

  1. ~Notepad();

以下各行声明一个成员变量,该成员变量是指向记事本UI类的指针。成员变量与特定的类相关联,并且可用于其所有方法。

  1. private:
  2. Ui::Notepad *ui;
  3. QString currentFile;

记事本源文件

向导为Notepad类生成的源文件如下所示:

  1. #include "notepad.h"
  2. #include "ui_notepad.h"
  3. Notepad::Notepad(QWidget *parent) :
  4. QMainWindow(parent),
  5. ui(new Ui::Notepad)
  6. {
  7. ui->setupUi(this);
  8. this->setCentralWidget(ui->textEdit);
  9. connect(ui->actionNew, &QAction::triggered, this, &Notepad::newDocument);
  10. connect(ui->actionOpen, &QAction::triggered, this, &Notepad::open);
  11. connect(ui->actionSave, &QAction::triggered, this, &Notepad::save);
  12. connect(ui->actionSave_as, &QAction::triggered, this, &Notepad::saveAs);
  13. connect(ui->actionPrint, &QAction::triggered, this, &Notepad::print);
  14. connect(ui->actionExit, &QAction::triggered, this, &Notepad::exit);
  15. connect(ui->actionCopy, &QAction::triggered, this, &Notepad::copy);
  16. connect(ui->actionCut, &QAction::triggered, this, &Notepad::cut);
  17. connect(ui->actionPaste, &QAction::triggered, this, &Notepad::paste);
  18. connect(ui->actionUndo, &QAction::triggered, this, &Notepad::undo);
  19. connect(ui->actionRedo, &QAction::triggered, this, &Notepad::redo);
  20. connect(ui->actionFont, &QAction::triggered, this, &Notepad::selectFont);
  21. connect(ui->actionBold, &QAction::triggered, this, &Notepad::setFontBold);
  22. connect(ui->actionUnderline, &QAction::triggered, this, &Notepad::setFontUnderline);
  23. connect(ui->actionItalic, &QAction::triggered, this, &Notepad::setFontItalic);
  24. connect(ui->actionAbout, &QAction::triggered, this, &Notepad::about);
  25. // Disable menu actions for unavailable features
  26. #if !defined(QT_PRINTSUPPORT_LIB) || !QT_CONFIG(printer)
  27. ui->actionPrint->setEnabled(false);
  28. #endif
  29. #if !QT_CONFIG(clipboard)
  30. ui->actionCut->setEnabled(false);
  31. ui->actionCopy->setEnabled(false);
  32. ui->actionPaste->setEnabled(false);
  33. #endif
  34. }
  35. Notepad::~Notepad()
  36. {
  37. delete ui;
  38. }
  39. void Notepad::newDocument()
  40. {
  41. currentFile.clear();
  42. ui->textEdit->setText(QString());
  43. }
  44. void Notepad::open()
  45. {
  46. QString fileName = QFileDialog::getOpenFileName(this, "Open the file");
  47. QFile file(fileName);
  48. currentFile = fileName;
  49. if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
  50. QMessageBox::warning(this, "Warning", "Cannot open file: " + file.errorString());
  51. return;
  52. }
  53. setWindowTitle(fileName);
  54. QTextStream in(&file);
  55. QString text = in.readAll();
  56. ui->textEdit->setText(text);
  57. file.close();
  58. }
  59. void Notepad::save()
  60. {
  61. QString fileName;
  62. // If we don't have a filename from before, get one.
  63. if (currentFile.isEmpty()) {
  64. fileName = QFileDialog::getSaveFileName(this, "Save");
  65. currentFile = fileName;
  66. } else {
  67. fileName = currentFile;
  68. }
  69. QFile file(fileName);
  70. if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
  71. QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
  72. return;
  73. }
  74. setWindowTitle(fileName);
  75. QTextStream out(&file);
  76. QString text = ui->textEdit->toPlainText();
  77. out << text;
  78. file.close();
  79. }
  80. void Notepad::saveAs()
  81. {
  82. QString fileName = QFileDialog::getSaveFileName(this, "Save as");
  83. QFile file(fileName);
  84. if (!file.open(QFile::WriteOnly | QFile::Text)) {
  85. QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
  86. return;
  87. }
  88. currentFile = fileName;
  89. setWindowTitle(fileName);
  90. QTextStream out(&file);
  91. QString text = ui->textEdit->toPlainText();
  92. out << text;
  93. file.close();
  94. }
  95. void Notepad::print()
  96. {
  97. #if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
  98. QPrinter printDev;
  99. #if QT_CONFIG(printdialog)
  100. QPrintDialog dialog(&printDev, this);
  101. if (dialog.exec() == QDialog::Rejected)
  102. return;
  103. #endif // QT_CONFIG(printdialog)
  104. ui->textEdit->print(&printDev);
  105. #endif // QT_CONFIG(printer)
  106. }
  107. void Notepad::exit()
  108. {
  109. QCoreApplication::quit();
  110. }
  111. void Notepad::copy()
  112. {
  113. #if QT_CONFIG(clipboard)
  114. ui->textEdit->copy();
  115. #endif
  116. }
  117. void Notepad::cut()
  118. {
  119. #if QT_CONFIG(clipboard)
  120. ui->textEdit->cut();
  121. #endif
  122. }
  123. void Notepad::paste()
  124. {
  125. #if QT_CONFIG(clipboard)
  126. ui->textEdit->paste();
  127. #endif
  128. }
  129. void Notepad::undo()
  130. {
  131. ui->textEdit->undo();
  132. }
  133. void Notepad::redo()
  134. {
  135. ui->textEdit->redo();
  136. }
  137. void Notepad::selectFont()
  138. {
  139. bool fontSelected;
  140. QFont font = QFontDialog::getFont(&fontSelected, this);
  141. if (fontSelected)
  142. ui->textEdit->setFont(font);
  143. }

以下各行包括由向导生成的Notepad类头文件和由uic工具生成的UI头文件:

  1. #include "notepad.h"
  2. #include "ui_notepad.h"

以下行定义了Notepad构造函数:

  1. Notepad::Notepad(QWidget *parent) :

以下行调用QMainWindow构造函数,该构造函数是Notepad类的基类:

  1. QMainWindow(parent),

以下行创建UI类实例并将其分配给ui成员

  1. ui(new Ui::Notepad)

以下行设置了UI:

  1. ui->setupUi(this);

在析构函数中,我们删除ui

  1. Notepad::~Notepad()
  2. {
  3. delete ui;
  4. }

为了使文本编辑字段占据整个屏幕,我们将其添加setCentralWidget到主窗口中。

  1. Notepad::Notepad(QWidget *parent) :
  2. QMainWindow(parent),
  3. ui(new Ui::Notepad)
  4. {
  5. ui->setupUi(this);
  6. this->setCentralWidget(ui->textEdit);
  7. connect(ui->actionNew, &QAction::triggered, this, &Notepad::newDocument);
  8. connect(ui->actionOpen, &QAction::triggered, this, &Notepad::open);
  9. connect(ui->actionSave, &QAction::triggered, this, &Notepad::save);
  10. connect(ui->actionSave_as, &QAction::triggered, this, &Notepad::saveAs);
  11. connect(ui->actionPrint, &QAction::triggered, this, &Notepad::print);
  12. connect(ui->actionExit, &QAction::triggered, this, &Notepad::exit);
  13. connect(ui->actionCopy, &QAction::triggered, this, &Notepad::copy);
  14. connect(ui->actionCut, &QAction::triggered, this, &Notepad::cut);
  15. connect(ui->actionPaste, &QAction::triggered, this, &Notepad::paste);
  16. connect(ui->actionUndo, &QAction::triggered, this, &Notepad::undo);
  17. connect(ui->actionRedo, &QAction::triggered, this, &Notepad::redo);
  18. connect(ui->actionFont, &QAction::triggered, this, &Notepad::selectFont);
  19. connect(ui->actionBold, &QAction::triggered, this, &Notepad::setFontBold);
  20. connect(ui->actionUnderline, &QAction::triggered, this, &Notepad::setFontUnderline);
  21. connect(ui->actionItalic, &QAction::triggered, this, &Notepad::setFontItalic);
  22. connect(ui->actionAbout, &QAction::triggered, this, &Notepad::about);
  23. // Disable menu actions for unavailable features
  24. #if !defined(QT_PRINTSUPPORT_LIB) || !QT_CONFIG(printer)
  25. ui->actionPrint->setEnabled(false);
  26. #endif
  27. #if !QT_CONFIG(clipboard)
  28. ui->actionCut->setEnabled(false);
  29. ui->actionCopy->setEnabled(false);
  30. ui->actionPaste->setEnabled(false);
  31. #endif
  32. }

工程文件

向导notepad.pro将为我们生成以下项目文件:

  1. TEMPLATE = app
  2. TARGET = notepad
  3. QT += widgets
  4. qtHaveModule(printsupport): QT += printsupport
  5. requires(qtConfig(fontdialog))
  6. SOURCES += \
  7. main.cpp\
  8. notepad.cpp
  9. HEADERS += notepad.h
  10. FORMS += notepad.ui
  11. RESOURCES += \
  12. notepad.qrc
  13. # install
  14. target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/notepad
  15. INSTALLS += target

项目文件指定应用程序名称和qmake用于生成项目的模板,以及项目中包含的源文件,头文件和UI文件。

您也可以使用qmake-project选项来生成.pro文件。尽管在这种情况下,您必须记住将行添加QT += widgets到生成的文件中才能链接到Qt Widgets模块。

添加用户互动

为了向编辑器添加功能,我们首先在工具栏上添加菜单项和按钮。

单击“在这里输入”,然后添加选项“新建”,“打开”,“保存”,“另存为”,“打印”和“退出”。

2021040112022468.png

这将在下面的”操作编辑器“中创建5行代码。要将操作连接到插槽,请右键单击一个操作,并选择Go To slot > triggered(),并完成给定插槽的代码。

如果我们还想向工具栏添加操作,我们可以为每个 QAction分配一个图标,然后将QAction拖到工具栏上。通过在相关操作的图标属性中输入图标名称来分配图标。当QAction被拖到工具栏上时,单击图标将启动相关的插槽。

完成方法newDocument()

  1. void Notepad::newDocument()
  2. {
  3. currentFile.clear();
  4. ui->textEdit->setText(QString());
  5. }

current_file是包含当前正在编辑的文件的全局变量。它在notepad.h的私有部分中定义:

  1. private:
  2. Ui::Notepad *ui;
  3. QString currentFile;

clear() 清除文本缓冲区。

打开文件

在notepad.ui中,右键单击actionOpen并选择Go to slot

  1. void Notepad::open()
  2. {
  3. QString fileName = QFileDialog::getOpenFileName(this, "Open the file");
  4. QFile file(fileName);
  5. currentFile = fileName;
  6. if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
  7. QMessageBox::warning(this, "Warning", "Cannot open file: " + file.errorString());
  8. return;
  9. }
  10. setWindowTitle(fileName);
  11. QTextStream in(&file);
  12. QString text = in.readAll();
  13. ui->textEdit->setText(text);
  14. file.close();
  15. }
  • QFileDialog::getOpenFileName打开一个对话框,使您可以选择文件。
  • QFile对象具有选定file_name的参数。我们还将所选文件名存储到全局变量current_file中,以备后用
  • file.open以只读文本文件的形式打开文件。如果无法打开,则会发出警告,然后程序停止。
  • file作为 QTextStream 的参数,文件的内容被复制到QString文本中,用填充我们编辑器的缓冲区 ui->textEdit->setText(text)。

保存文件

我们创建保存文件的方法与打开文件的方法相同,方法是右键单击actionSave,并选择Go to Slot。

  1. void Notepad::save()
  2. {
  3. QString fileName;
  4. // If we don't have a filename from before, get one.
  5. if (currentFile.isEmpty()) {
  6. fileName = QFileDialog::getSaveFileName(this, "Save");
  7. currentFile = fileName;
  8. } else {
  9. fileName = currentFile;
  10. }
  11. QFile file(fileName);
  12. if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
  13. QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
  14. return;
  15. }
  16. setWindowTitle(fileName);
  17. QTextStream out(&file);
  18. QString text = ui->textEdit->toPlainText();
  19. out << text;
  20. file.close();
  21. }

QFile对象myfile链接到全局变量current_file,该变量包含我们正在使用的文件。如果我们无法打开myfile,就会发出一条错误消息,并停止该方法。我们创建一个QTextStream输出流。编辑器缓冲区的内容被转换为纯文本,然后被写入outstream。

另存为

  1. void Notepad::saveAs()
  2. {
  3. QString fileName = QFileDialog::getSaveFileName(this, "Save as");
  4. QFile file(fileName);
  5. if (!file.open(QFile::WriteOnly | QFile::Text)) {
  6. QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
  7. return;
  8. }
  9. currentFile = fileName;
  10. setWindowTitle(fileName);
  11. QTextStream out(&file);
  12. QString text = ui->textEdit->toPlainText();
  13. out << text;
  14. file.close();
  15. }

这与保存文件的过程相同,唯一的区别是您需要为要创建的文件输入一个新文件名。

打印文件

如果要使用打印功能,则需要添加printsupport到项目文件中:

  1. QT += printsupport

我们声明一个名为printer的QPrinter对象。我们启动一个打印机对话框,并将选中的打印机存储在object printer中。如果单击Cancel并且没有选择打印机,则该方法将返回。实际的打印机命令是通过ui->textEdit->print和我们的QPrinter对象作为参数给出的。

Copy, Cut, Paste, Undo, and Redo

如果您选择了一些文本,并希望将其复制到剪贴板,您可以调用ui->textEdit的适当方法。剪切、粘贴、撤消和重做的计数相同。

该表显示了要使用的方法名。






























任务 方法调用
复制 ui-> textEdit-> copy()
剪切 ui-> textEdit-> cut()
粘贴 ui-> textEdit-> paste()
撤消 ui-> textEdit-> undo()
重做 ui-> textEdit-> redo()

构建和运行记事本

现在您有了所有必需的文件,选择Build > Build Project Notepad来构建和运行应用程序。Qt Creator使用qmake和make在项目的构建设置中指定的目录中创建可执行文件并运行它。

从命令行构建和运行

要从命令行构建应用程序,请切换到包含应用程序的.cpp文件的目录,并添加前面描述的项目文件(后缀为.pro)。然后使用以下shell命令构建应用程序:

  1. qmake
  2. make (or nmake on Windows)

这些命令在项目目录中创建一个可执行文件。qmake工具读取项目文件并生成一个Makefile,其中包含如何构建应用程序的说明。然后,make工具(或nmake工具)读取Makefile并生成可执行二进制文件。

Example project @ code.qt.io

扩展


















关于 这里
使用Qt Creator Qt创作者
使用Qt Creator创建其他类型的应用程序 Qt Creator教程

















关于 这里
小部件和窗口几何 窗口和对话框小部件
事件和事件处理 事件系统

































关于 这里
使用Qt Designer Qt Designer手册
版面 布局管理小部件和布局布局示例
Qt附带的小部件 Qt小工具库
主窗口和主窗口类 应用程序主窗口主窗口示例
QObjects和Qt对象模型(这对于理解Qt是必不可少的) 对象模型
qmake和Qt构建系统 qmake手册





















关于 这里
MDI应用 QMdiAreaMDI示例
文件和I / O设备 QFile时QIODevice中
tr()与国际化 Qt语言手册编写源代码翻译国际化使用Qt

发表评论

表情:
评论列表 (有 0 条评论,521人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Flutter widget目录

    这是个Flutter教学系列的文章,会从Flutter基础入门开始讲解,带领大家从零开始学习Flutter,从基础组件一个一个的过,可以保证每个没有Flutter开发基础的同学

    相关 Qt:Qt Widgets

    [Qt Widgets][]提供了一组UI元素,以创建经典的桌面式用户界面,有关使用小部件的更多信息,见参阅[用户界面][Link 1]概叙 部件(Widgets) [

    相关 CocosCreator Widget总结

    这里的总结,我们主要来说一下widget.updateAlignment()这个方法的坑和解决的办法。 在详细说明之前,有必要交代一下我测试的版本为1.9.3,然后,希望大家

    相关 Flutter Widget大全

    还没有做完,应该是目前最全的Widget介绍了,如果需要使用什么控件在这里找就行,如果还没有就得自定义Widget了,欢迎点赞支持我继续把图做完,这个图没什么技术含量,大部分就