Catalog
1.2 Create a resource file (myimages.qrc)
1.3 Create an interface file (mainwindow.ui)
1.2 MainWindow class code is as follows
Use qt5 to write a project with multi-document editor functions (can write multiple documents, save, open, edit, undo, cut, copy, paste, and so on).
ps: This project is developed using Qt5.6 and Chapter 1 of "Qt and Qt Quick Development of Actual Combat Resolution". (The original book was developed using Qt4.7 and Qt Creator 2.1.0).
Here's how the program works:
Attach program and source address:
Links: https://pan.baidu.com/s/1sNCOUqrQnX0Com6zxZhfKA
Extraction Code: idug
I. Preparations
Prepare the desired icon file (preferably one with practical icons), save it as a Qt resource file, call it later, and use the ui to design the window interface.
1.1 Create a project
Open Qt Creator, create a new project, create a new Application ->Qt Widgets Application project name changed to myMid
Set the base class to QMainWindow. The creation was successful as follows:
1.2 Create a resource file (myimages.qrc)
Right-click the project name, add a new file, select Qt Resource File, change the file name to myimages.qrc, click myimages.qrc, and add a prefix name/images to the add menu bar below. Then create a new folder in the project directory called images and put the icon file in it (it can be in any format such as. **ico **.png **.jpg, but the file size is not too large). Back in myimages.qrc, add the image file you just created to images by adding the file from the Add menu. Add it as follows
1.3 Create an interface file (mainwindow.ui)
These operational UI interfaces are designed. Change the names of the four Run menu items to menuF,menuE,menuW,menuH.
Can run to see the effect;
2. Implementing Functions
Let each module implement its own functions, such as opening files, copying and pasting, undoing and so on.
1.1 New c++class
Right-click the new c++class base class in the project and select the QDialog class named MdiChild.
MdiChild.h:
#ifndef MDICHILD_H #define MDICHILD_H #include <QTextEdit> class MdiChild : public QTextEdit { Q_OBJECT public: explicit MdiChild(QWidget *parent = 0); void newFile(); // New Operation bool loadFile(const QString &fileName); // load file bool save(); // Save Operation bool saveAs(); // Save As Operation bool saveFile(const QString &fileName); // Save File QString userFriendlyCurrentFile(); // Extract File Name QString currentFile(){return curFile;} // Return to current file path protected: void closeEvent(QCloseEvent *event); // Close Event void contextMenuEvent(QContextMenuEvent *e); // Right-click menu events private slots: void documentWasModified(); // Display change status flag when document is changed private: bool maybeSave(); // Do you need to save void setCurrentFile(const QString &fileName); // Set Current File QString curFile; // Save the current file path bool isUntitled; // As a flag whether the current file is saved to the hard disk or not }; #endif // MDICHILD_H
MdiChild.cpp
#include "mdichild.h" #include <QFile> #include <QTextStream> #include <QMessageBox> #include <QFileInfo> #include <QApplication> #include <QFileDialog> #include <QCloseEvent> #include <QPushButton> #include <QMenu> #include <qtextcodec.h> MdiChild::MdiChild(QWidget *parent) : QTextEdit(parent) { setAttribute(Qt::WA_DeleteOnClose); // This will destroy objects of this class when the child window closes isUntitled = true; // Initial isUntitled is true } QTextCodec *codec1 = QTextCodec::codecForName("GB2312");//Show as Chinese Character void MdiChild::newFile() // New File Operation { static int sequenceNumber = 1; // Set the window number because it is always saved, so you need to use a static variable isUntitled = true; // New document not saved // Name the current file unnamed and numbered. Use the numbering first and add 1 curFile = codec1->toUnicode("Unnamed Document%1.txt").arg(sequenceNumber++); // Set the window title, use [*] to display "*" number after the file name is changed setWindowTitle(curFile + "[*]" + codec1->toUnicode(" - Xiao Yi Multi-document Editor")); // Sends a contentsChanged() signal when the document is changed. // Execute our documentWasModified() slot function connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified())); } void MdiChild::documentWasModified() //When a document is changed, the window displays a change status flag { // Determine if our editor content has changed based on the return value of the document's isModified() function // If it's changed, the'*'sign will be displayed where the [*] sign is set, and here we'll show it in the window title setWindowModified(document()->isModified()); } bool MdiChild::loadFile(const QString &fileName) // load file { QFile file(fileName); // New QFile Object if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, codec1->toUnicode("Xiao Yi Multi-document Editor"), codec1->toUnicode("Unable to read file %1:\n%2.") .arg(fileName).arg(file.errorString())); return false; // Open the file read-only, prompt for errors, and return false } QTextStream in(&file); // New Text Flow Object QApplication::setOverrideCursor(Qt::WaitCursor); // Set the mouse state to wait setPlainText(in.readAll()); // Read the entire text of the file and add it to the editor QApplication::restoreOverrideCursor(); // Restore mouse state setCurrentFile(fileName); // Set Current File connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified())); return true; } void MdiChild::setCurrentFile(const QString &fileName) // Set Current File { // canonicalFilePath() removes symbolic links in paths, such as'. 'and'.'. curFile = QFileInfo(fileName).canonicalFilePath(); isUntitled = false; // The file has been saved document()->setModified(false); // Document has not been changed setWindowModified(false); // Window does not display changed flag // Set the window title, userFriendlyCurrentFile() returns the file name setWindowTitle(userFriendlyCurrentFile() + "[*]"); } QString MdiChild::userFriendlyCurrentFile() // Extract File Name { return QFileInfo(curFile).fileName(); // Extract file name from file path } bool MdiChild::save() // Save Operation { if (isUntitled) { // Save as operation if file has not been saved return saveAs(); } else { return saveFile(curFile); // Otherwise save the file directly } } bool MdiChild::saveAs() // Save As Operation { // Gets the file path and returns false if it is empty QString fileName = QFileDialog::getSaveFileName(this, codec1->toUnicode("Save As"),curFile); if (fileName.isEmpty()) return false; return saveFile(fileName); // Otherwise save the file } bool MdiChild::saveFile(const QString &fileName) // Save File { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, codec1->toUnicode("Xiao Yi Multi-document Editor"), codec1->toUnicode("Cannot write to file %1:\n%2.") .arg(fileName).arg(file.errorString())); return false; } QTextStream out(&file); QApplication::setOverrideCursor(Qt::WaitCursor); out << toPlainText(); // Write as plain text file QApplication::restoreOverrideCursor(); setCurrentFile(fileName); return true; } void MdiChild::closeEvent(QCloseEvent *event) { if (maybeSave()) { // Close the window if the maybeSave() function returns true event->accept(); } else { // Otherwise ignore the event event->ignore(); } } bool MdiChild::maybeSave() // Do you need to save { if (document()->isModified()) { // If the document has been changed QMessageBox box; box.setWindowTitle(codec1->toUnicode("Xiao Yi Multi-document Editor")); box.setText(codec1->toUnicode("Whether to save pairs of%1"Change?") .arg(userFriendlyCurrentFile())); box.setIcon(QMessageBox::Warning); // Add button, QMessageBox::YesRole can indicate the behavior of this button QPushButton *yesBtn = box.addButton(codec1->toUnicode("yes(&Y)"),QMessageBox::YesRole); box.addButton(codec1->toUnicode("no(&N)"),QMessageBox::NoRole); QPushButton *cancelBtn = box.addButton(codec1->toUnicode("cancel"), QMessageBox::RejectRole); box.exec(); // Pop up a dialog box to let the user choose whether to save the changes or cancel the close operation if (box.clickedButton() == yesBtn)// Returns the result of the save operation if the user chooses yes return save(); else if (box.clickedButton() == cancelBtn) // Return false if you choose to cancel return false; } return true; // Return true directly if the document has not changed } void MdiChild::contextMenuEvent(QContextMenuEvent *e) // Right-click menu events { QMenu *menu = new QMenu; // Create a menu and add actions to it QAction *undo = menu->addAction(codec1->toUnicode("Revoke(&U)"),this, SLOT(undo()),QKeySequence::Undo); undo->setEnabled(document()->isUndoAvailable()); QAction *redo = menu->addAction(codec1->toUnicode("recovery(&R)"),this, SLOT(redo()),QKeySequence::Redo); redo->setEnabled(document()->isRedoAvailable()); menu->addSeparator(); QAction *cut = menu->addAction(codec1->toUnicode("shear(&T)"),this, SLOT(cut()),QKeySequence::Cut); cut->setEnabled(textCursor().hasSelection()); QAction *copy = menu->addAction(codec1->toUnicode("copy(&C)"),this, SLOT(copy()),QKeySequence::Copy); copy->setEnabled(textCursor().hasSelection()); menu->addAction(codec1->toUnicode("paste(&P)"),this,SLOT(paste()),QKeySequence::Paste); QAction *clear = menu->addAction(codec1->toUnicode("empty"),this,SLOT(clear())); clear->setEnabled(!document()->isEmpty()); menu->addSeparator(); QAction *select = menu->addAction(codec1->toUnicode("Select All"),this, SLOT(selectAll()),QKeySequence::SelectAll); select->setEnabled(!document()->isEmpty()); menu->exec(e->globalPos()); // Get the location of the mouse and display the menu in that location delete menu; // Finally destroy this menu }
1.2 MainWindow class code is as follows
MainWindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> class MdiChild; class QMdiSubWindow; class QSignalMapper; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_actionNew_triggered(); // New File Menu void updateMenus(); // Update Menu MdiChild *createMdiChild(); // Create subwindows void setActiveSubWindow(QWidget *window); // Set Active Subwindow void on_actionOpen_triggered(); // Open File Menu void updateWindowMenu(); // Update Window Menu void on_actionSave_triggered(); void on_actionSaveAs_triggered(); void on_actionUndo_triggered(); void on_actionRedo_triggered(); void on_actionCut_triggered(); void on_actionCopy_triggered(); void on_actionPaste_triggered(); void on_actionClose_triggered(); void on_actionCloseAll_triggered(); void on_actionTile_triggered(); void on_actionCascade_triggered(); void on_actionNext_triggered(); void on_actionPrevious_triggered(); void on_actionAbout_triggered(); void on_actionAboutQt_triggered(); void on_actionExit_triggered(); void showTextRowAndCol(); // Display line and column numbers for text private: Ui::MainWindow *ui; QAction *actionSeparator; // Separator MdiChild *activeMdiChild(); // Active Window QMdiSubWindow *findMdiChild(const QString &fileName);// Find child windows QSignalMapper *windowMapper; // Signal Mapper void readSettings(); // Read Window Settings void writeSettings(); // Write window settings void initWindow(); // Initialization window protected: void closeEvent(QCloseEvent *event); // Close Event }; #endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "mdichild.h" #include <QMdiSubWindow> #include <QFileDialog> #include <QSignalMapper> #include <QMessageBox> #include <QSettings> #include <QCloseEvent> #include <QLabel> #include <qtextcodec.h> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); actionSeparator = new QAction(this); // Create Interceptor Action actionSeparator->setSeparator(true); // Set the spacer in it updateMenus(); // Update Menu connect(ui->mdiArea,SIGNAL(subWindowActivated(QMdiSubWindow*)),this, SLOT(updateMenus())); // Update menu when there is an active window windowMapper = new QSignalMapper(this); // Create Signal Mapper connect(windowMapper, SIGNAL(mapped(QWidget*)), // Mapper Re-transmit Signal this, SLOT(setActiveSubWindow(QWidget*))); // Set Active Window // Update the window menu, and set the window menu to be updated when it is about to be displayed updateWindowMenu(); connect(ui->menuW,SIGNAL(aboutToShow()),this,SLOT(updateWindowMenu())); readSettings(); // Read window settings information at initial window initWindow(); // Initialization window } QTextCodec *codec = QTextCodec::codecForName("GB2312"); MainWindow::~MainWindow() { delete ui; } void MainWindow::on_actionNew_triggered() // New File Menu { MdiChild *child = createMdiChild(); // Create MdiChild child->newFile(); // new file child->show(); // Show child windows } MdiChild * MainWindow::createMdiChild() // Create child widgets { MdiChild *child = new MdiChild; // Create MdiChild Part ui->mdiArea->addSubWindow(child); // Add a child window to a multi-document area with child as the central part // Set whether the cut-copy action is available based on whether the QTextEdit class can replicate the signal connect(child,SIGNAL(copyAvailable(bool)),ui->actionCut, SLOT(setEnabled(bool))); connect(child,SIGNAL(copyAvailable(bool)),ui->actionCopy, SLOT(setEnabled(bool))); // Set whether the undo recovery action is available based on whether the QTextDocument class can undo the recovery signal connect(child->document(),SIGNAL(undoAvailable(bool)), ui->actionUndo,SLOT(setEnabled(bool))); connect(child->document(),SIGNAL(redoAvailable(bool)), ui->actionRedo,SLOT(setEnabled(bool))); // Whenever the cursor position in the editor changes, the row and column numbers are displayed again connect(child,SIGNAL(cursorPositionChanged()),this,SLOT(showTextRowAndCol())); return child; } void MainWindow::updateMenus() // Update Menu { bool hasMdiChild = (activeMdiChild() != 0); // Is there an active window ui->actionSave->setEnabled(hasMdiChild); // Set whether each action is available ui->actionSaveAs->setEnabled(hasMdiChild); ui->actionPaste->setEnabled(hasMdiChild); ui->actionClose->setEnabled(hasMdiChild); ui->actionCloseAll->setEnabled(hasMdiChild); ui->actionTile->setEnabled(hasMdiChild); ui->actionCascade->setEnabled(hasMdiChild); ui->actionNext->setEnabled(hasMdiChild); ui->actionPrevious->setEnabled(hasMdiChild); actionSeparator->setVisible(hasMdiChild); // Set whether the spacer is displayed bool hasSelection = (activeMdiChild() && activeMdiChild()->textCursor().hasSelection()); // Cut-and-copy is only available if there is an active window and selected text ui->actionCut->setEnabled(hasSelection); ui->actionCopy->setEnabled(hasSelection); ui->actionUndo->setEnabled(activeMdiChild() // Has active window and document has undo action && activeMdiChild()->document()->isUndoAvailable()); ui->actionRedo->setEnabled(activeMdiChild() // Active window and document recovery && activeMdiChild()->document()->isRedoAvailable()); } MdiChild * MainWindow::activeMdiChild() // Active Window { // If there is an active window, convert the central part inside to the MdiChild type if (QMdiSubWindow *activeSubWindow = ui->mdiArea->activeSubWindow()) return qobject_cast<MdiChild *>(activeSubWindow->widget()); return 0; // No active window, return 0 directly } void MainWindow::on_actionOpen_triggered() // Open File Menu { QString fileName = QFileDialog::getOpenFileName(this); // Get File Path if (!fileName.isEmpty()) { // If the path is not empty, check to see if the file is open QMdiSubWindow *existing = findMdiChild(fileName); if (existing) { // If it already exists, set the corresponding child window as the active window ui->mdiArea->setActiveSubWindow(existing); return; } MdiChild *child = createMdiChild(); // If not, create a new subwindow if (child->loadFile(fileName)) { ui->statusBar->showMessage(codec->toUnicode("Open File Successfully"), 2000); child->show(); } else { child->close(); } } } QMdiSubWindow * MainWindow::findMdiChild(const QString &fileName) // Find child windows { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); // Use the foreach statement to iterate through the list of subwindows and return the window if its file path is the same as the path you are looking for foreach (QMdiSubWindow *window, ui->mdiArea->subWindowList()) { MdiChild *mdiChild = qobject_cast<MdiChild *>(window->widget()); if (mdiChild->currentFile() == canonicalFilePath) return window; } return 0; } void MainWindow::setActiveSubWindow(QWidget *window) // Set Active Subwindow { if (!window) // If a widget is passed, set it as the active window return; ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window)); } void MainWindow::updateWindowMenu() // Update Window Menu { ui->menuW->clear(); // Empty the menu before adding individual menu actions ui->menuW->addAction(ui->actionClose); ui->menuW->addAction(ui->actionCloseAll); ui->menuW->addSeparator(); ui->menuW->addAction(ui->actionTile); ui->menuW->addAction(ui->actionCascade); ui->menuW->addSeparator(); ui->menuW->addAction(ui->actionNext); ui->menuW->addAction(ui->actionPrevious); ui->menuW->addAction(actionSeparator); QList<QMdiSubWindow *> windows = ui->mdiArea->subWindowList(); actionSeparator->setVisible(!windows.isEmpty()); // Show spacer if there is an active window for (int i = 0; i < windows.size(); ++i) { // Traverse through subwindows MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget()); QString text; if (i < 9) { // Number as shortcut if the number of windows is less than 9 text = tr("&%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile()); } else { text = tr("%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile()); } QAction *action = ui->menuW->addAction(text); // Add Action to Menu action->setCheckable(true); // Set action to select // Set current active window action to selected state action ->setChecked(child == activeMdiChild()); // The trigger signal associated with the action is placed on the map() slot function of the signal mapper, which emits the mapped() signal connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); // Map the action to the corresponding widget, which is used as a parameter when the mapped() signal is sent windowMapper->setMapping(action, windows.at(i)); } } /********************1.3.3 The following codes are partially omitted in the subsection ****************************************/ void MainWindow::on_actionSave_triggered() // Save Menu { if(activeMdiChild() && activeMdiChild()->save()) ui->statusBar->showMessage(codec->toUnicode("File saved successfully"),2000); } void MainWindow::on_actionSaveAs_triggered() // Save as Menu { if(activeMdiChild() && activeMdiChild()->saveAs()) ui->statusBar->showMessage(codec->toUnicode("File saved successfully"),2000); } void MainWindow::on_actionUndo_triggered() // Undo Menu { if(activeMdiChild()) activeMdiChild()->undo(); } void MainWindow::on_actionRedo_triggered() // Recovery Menu { if(activeMdiChild()) activeMdiChild()->redo(); } void MainWindow::on_actionCut_triggered() // Cut Menu { if(activeMdiChild()) activeMdiChild()->cut(); } void MainWindow::on_actionCopy_triggered() // Copy Menu { if(activeMdiChild()) activeMdiChild()->copy(); } void MainWindow::on_actionPaste_triggered() // Paste Menu { if(activeMdiChild()) activeMdiChild()->paste(); } void MainWindow::on_actionClose_triggered() // Close Menu { ui->mdiArea->closeActiveSubWindow(); } void MainWindow::on_actionCloseAll_triggered() // Close all window menus { ui->mdiArea->closeAllSubWindows(); } void MainWindow::on_actionTile_triggered() // Tile menu { ui->mdiArea->tileSubWindows(); } void MainWindow::on_actionCascade_triggered() // Cascade menu { ui->mdiArea->cascadeSubWindows(); } void MainWindow::on_actionNext_triggered() // Next Menu { ui->mdiArea->activateNextSubWindow(); } void MainWindow::on_actionPrevious_triggered() // Previous Menu { ui->mdiArea->activatePreviousSubWindow(); } void MainWindow::on_actionAbout_triggered() // About Menus { QMessageBox::about(this,codec->toUnicode("About this software"),codec->toUnicode("Welcome to me csdn Home page: https://blog.csdn.net/qq_46424406?spm=1003.2020.3001.5343")); } void MainWindow::on_actionAboutQt_triggered() // About Qt Menu { qApp->aboutQt(); // Here, qApp is the global pointer to the QApplication object. // This line of code is equivalent to QApplication::aboutQt(); } void MainWindow::on_actionExit_triggered() // Exit Menu { qApp->closeAllWindows(); // Equivalent to QApplication::closeAllWindows(); } void MainWindow::closeEvent(QCloseEvent *event) // Close Event { ui->mdiArea->closeAllSubWindows(); // Perform multi-document area closure first if (ui->mdiArea->currentSubWindow()) { event->ignore(); // Ignore this event if there are windows left open } else { writeSettings(); // Write window settings before closing event->accept(); } } void MainWindow::writeSettings() // Write window settings { QSettings settings("yafeilinux", "myMdi"); settings.setValue("pos", pos()); // Write location information settings.setValue("size", size()); // Write size information } void MainWindow::readSettings() // Read Window Settings { QSettings settings("yafeilinux", "myMdi"); QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); QSize size = settings.value("size", QSize(400, 400)).toSize(); move(pos); resize(size); } void MainWindow::showTextRowAndCol() // Display line and column numbers for text { // If there is an active window, the location of the cursor is displayed if(activeMdiChild()){ // Because both row and column numbers are obtained from zero, we add 1 here int rowNum = activeMdiChild()->textCursor().blockNumber()+1; int colNum = activeMdiChild()->textCursor().columnNumber()+1; ui->statusBar->showMessage(tr("%1 That's ok %2 column") .arg(rowNum).arg(colNum),2000); } } void MainWindow::initWindow() // Initialization window { setWindowTitle(codec->toUnicode("Xiao Yi Multi-document Editor")); // You can close the toolbar when you right-click on it ui->mainToolBar->setWindowTitle(codec->toUnicode("toolbar")); // Scrollbars appear when the contents of a multi-document area exceed the visible area ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); ui->statusBar->showMessage(codec->toUnicode("Welcome to Xiaoyi Document Editor")); QLabel *label = new QLabel(this); label->setFrameStyle(QFrame::Box | QFrame::Sunken); label->setText( tr("<a href=\"https://blog.csdn.net/qq_46424406?spm=1003.2020.3001.5343\">xiaoyi.com</a>")); label->setTextFormat(Qt::RichText); // Label text is rich text label->setOpenExternalLinks(true); // Can open external links ui->statusBar->addPermanentWidget(label); ui->actionNew->setStatusTip(codec->toUnicode("Create a file")); ui->actionOpen->setStatusTip(codec->toUnicode("Open an existing file")); ui->actionSave->setStatusTip(codec->toUnicode("Save Document to Hard Disk")); ui->actionSaveAs->setStatusTip(codec->toUnicode("Save the document with a new name")); ui->actionExit->setStatusTip(codec->toUnicode("exit from application program")); ui->actionUndo->setStatusTip(codec->toUnicode("Undo previous action")); ui->actionRedo->setStatusTip(codec->toUnicode("Restore previous operations")); ui->actionCut->setStatusTip(codec->toUnicode("Cut the selection to the clipboard")); ui->actionCopy->setStatusTip(codec->toUnicode("Copy the selection to the clipboard")); ui->actionPaste->setStatusTip(codec->toUnicode("Paste the contents of the clipboard to the current location")); ui->actionClose->setStatusTip(codec->toUnicode("close the active window")); ui->actionCloseAll->setStatusTip(codec->toUnicode("Close all windows")); ui->actionTile->setStatusTip(codec->toUnicode("Tile all windows")); ui->actionCascade->setStatusTip(codec->toUnicode("Cascade all windows")); ui->actionNext->setStatusTip(codec->toUnicode("Move focus to next window")); ui->actionPrevious->setStatusTip(codec->toUnicode("Move focus to the previous window")); ui->actionAbout->setStatusTip(codec->toUnicode("Display an introduction to this software")); }
1.3 Principal Functions
main.cpp
#include <QtWidgets/QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
That's all the code block.
Successfully running has already achieved a basic Notepad function.
3. Procedure Release
Publishing a QT program requires setting the program icon, which is my shark icon. Just design a.Ico file with the file name set to my.ico and add it in the.pro file.
RC_ICONS = my.ico
Then compile, compile using Release, and after successful compilation, you can find a release file in the project directory, which contains a.Exe file, where I am myMdi.exe
But this file cannot be sent directly to someone else (because there is no running environment) so we need to package and publish it.
You can add it through the Qt command window and enter it in the Qt command
windeployqt Route
What I've entered here is
windeployqt C:\Users\XiaoYi\Desktop\myapp
There are some files added in the original folder as follows
Compression is now ready for publication;
summary
This is all the code that Qt writes for a notebook, with the release file and all the project code in the previous section. Most of this code is based on the source code of "Qt and Qt Quick Development Actual Combat Resolution", but it is only implemented on Qt5. The content may be unreasonable. Please correct.