Move widgets Application example to manual tests
With 6e77da640aa84c1efe330d4a5224c9c7425ece57, the documentviewer demo's TxtViewer plugin has been fully documented in order to replace the Application example. This patch moves the application example to manual tests. Pick-to: 6.5 Change-Id: I67d975e478c7bc840613c8af1301a4eafe8f1a42 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 39 KiB |
@ -1,370 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example mainwindows/application
|
||||
\title Qt Widgets - Application Example
|
||||
\ingroup examples-mainwindow
|
||||
|
||||
\brief The Application example shows how to implement a standard
|
||||
widget application with menus, toolbars, and a status bar. The example
|
||||
itself is a simple text editor program built around QPlainTextEdit.
|
||||
|
||||
\image application.png Screenshot of the Application example
|
||||
|
||||
Nearly all of the code for the Application example is in the \c
|
||||
MainWindow class, which inherits QMainWindow. QMainWindow
|
||||
provides the framework for windows that have menus, toolbars,
|
||||
dock windows, and a status bar. The application provides
|
||||
\uicontrol{File}, \uicontrol{Edit}, and \uicontrol{Help} entries in the menu
|
||||
bar, with the following popup menus:
|
||||
|
||||
\image application-menus.png The Application example's menu system
|
||||
|
||||
The status bar at the bottom of the main window shows a
|
||||
description of the menu item or toolbar button under the cursor.
|
||||
|
||||
To keep the example simple, recently opened files aren't shown in
|
||||
the \uicontrol{File} menu, even though this feature is desired in 90%
|
||||
of applications. Furthermore, this example can only load one file at a
|
||||
time. The \l{mainwindows/mdi}{MDI} example shows how to lift these
|
||||
restrictions and how to implement recently opened files handling.
|
||||
|
||||
\section1 MainWindow Class Definition
|
||||
|
||||
Here's the class definition:
|
||||
|
||||
\snippet mainwindows/application/mainwindow.h 0
|
||||
|
||||
The public API is restricted to the constructor. In the \c
|
||||
protected section, we reimplement QWidget::closeEvent() to detect
|
||||
when the user attempts to close the window, and warn the user
|
||||
about unsaved changes. In the \c{private slots} section, we
|
||||
declare slots that correspond to menu entries, as well as a
|
||||
mysterious \c documentWasModified() slot. Finally, in the \c
|
||||
private section of the class, we have various members that will
|
||||
be explained in due time.
|
||||
|
||||
\section1 MainWindow Class Implementation
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 0
|
||||
|
||||
We start by including \c <QtWidgets>, a header file that contains the
|
||||
definition of all classes in the Qt Core, Qt GUI and Qt Widgets
|
||||
modules. This saves us from the trouble of having to include
|
||||
every class individually. We also include \c mainwindow.h.
|
||||
|
||||
You might wonder why we don't include \c <QtWidgets> in \c
|
||||
mainwindow.h and be done with it. The reason is that including
|
||||
such a large header from another header file can rapidly degrade
|
||||
performances. Here, it wouldn't do any harm, but it's still
|
||||
generally a good idea to include only the header files that are
|
||||
strictly necessary from another header file.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 1
|
||||
\snippet mainwindows/application/mainwindow.cpp 2
|
||||
|
||||
In the constructor, we start by creating a QPlainTextEdit widget as a
|
||||
child of the main window (the \c this object). Then we call
|
||||
QMainWindow::setCentralWidget() to tell that this is going to be
|
||||
the widget that occupies the central area of the main window,
|
||||
between the toolbars and the status bar.
|
||||
|
||||
Then we call \c createActions() and \c createStatusBar(), two private
|
||||
functions that set up the user interface. After that, we call \c
|
||||
readSettings() to restore the user's preferences.
|
||||
|
||||
We establish a signal-slot connection between the QPlainTextEdit's
|
||||
document object and our \c documentWasModified() slot. Whenever
|
||||
the user modifies the text in the QPlainTextEdit, we want to update
|
||||
the title bar to show that the file was modified.
|
||||
|
||||
At the end, we set the window title using the private
|
||||
\c setCurrentFile() function. We'll come back to this later.
|
||||
|
||||
\target close event handler
|
||||
\snippet mainwindows/application/mainwindow.cpp 3
|
||||
\snippet mainwindows/application/mainwindow.cpp 4
|
||||
|
||||
When the user attempts to close the window, we call the private
|
||||
function \c maybeSave() to give the user the possibility to save
|
||||
pending changes. The function returns true if the user wants the
|
||||
application to close; otherwise, it returns false. In the first
|
||||
case, we save the user's preferences to disk and accept the close
|
||||
event; in the second case, we ignore the close event, meaning
|
||||
that the application will stay up and running as if nothing
|
||||
happened.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 5
|
||||
\snippet mainwindows/application/mainwindow.cpp 6
|
||||
|
||||
The \c newFile() slot is invoked when the user selects
|
||||
\uicontrol{File|New} from the menu. We call \c maybeSave() to save any
|
||||
pending changes and if the user accepts to go on, we clear the
|
||||
QPlainTextEdit and call the private function \c setCurrentFile() to
|
||||
update the window title and clear the
|
||||
\l{QWidget::windowModified}{windowModified} flag.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 7
|
||||
\snippet mainwindows/application/mainwindow.cpp 8
|
||||
|
||||
The \c open() slot is invoked when the user clicks
|
||||
\uicontrol{File|Open}. We pop up a QFileDialog asking the user to
|
||||
choose a file. If the user chooses a file (i.e., \c fileName is
|
||||
not an empty string), we call the private function \c loadFile()
|
||||
to actually load the file.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 9
|
||||
\snippet mainwindows/application/mainwindow.cpp 10
|
||||
|
||||
The \c save() slot is invoked when the user clicks
|
||||
\uicontrol{File|Save}. If the user hasn't provided a name for the file
|
||||
yet, we call \c saveAs(); otherwise, we call the private function
|
||||
\c saveFile() to actually save the file.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 11
|
||||
\snippet mainwindows/application/mainwindow.cpp 12
|
||||
|
||||
In \c saveAs(), we start by popping up a QFileDialog asking the
|
||||
user to provide a name. If the user clicks \uicontrol{Cancel}, the
|
||||
returned file name is empty, and we do nothing.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 13
|
||||
\snippet mainwindows/application/mainwindow.cpp 14
|
||||
|
||||
The application's About box is done using one statement, using
|
||||
the QMessageBox::about() static function and relying on its
|
||||
support for an HTML subset.
|
||||
|
||||
The \l{QObject::tr()}{tr()} call around the literal string marks
|
||||
the string for translation. It is a good habit to call
|
||||
\l{QObject::tr()}{tr()} on all user-visible strings, in case you
|
||||
later decide to translate your application to other languages.
|
||||
The \l{Internationalization with Qt} overview covers
|
||||
\l{QObject::tr()}{tr()} in more detail.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 15
|
||||
\snippet mainwindows/application/mainwindow.cpp 16
|
||||
|
||||
The \c documentWasModified() slot is invoked each time the text
|
||||
in the QPlainTextEdit changes because of user edits. We call
|
||||
QWidget::setWindowModified() to make the title bar show that the
|
||||
file was modified. How this is done varies on each platform.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 17
|
||||
\snippet mainwindows/application/mainwindow.cpp 18
|
||||
\dots
|
||||
\snippet mainwindows/application/mainwindow.cpp 22
|
||||
|
||||
The \c createActions() private function, which is called from the
|
||||
\c MainWindow constructor, creates \l{QAction}s and populates
|
||||
the menus and two toolbars. The code is very
|
||||
repetitive, so we show only the actions corresponding to
|
||||
\uicontrol{File|New}, \uicontrol{File|Open}, and \uicontrol{Help|About Qt}.
|
||||
|
||||
A QAction is an object that represents one user action, such as
|
||||
saving a file or invoking a dialog. An action can be put in a
|
||||
QMenu or a QToolBar, or both, or in any other widget that
|
||||
reimplements QWidget::actionEvent().
|
||||
|
||||
An action has a text that is shown in the menu, an icon, a
|
||||
shortcut key, a tooltip, a status tip (shown in the status bar),
|
||||
a "What's This?" text, and more. It emits a
|
||||
\l{QAction::triggered()}{triggered()} signal whenever the user
|
||||
invokes the action (e.g., by clicking the associated menu item or
|
||||
toolbar button).
|
||||
|
||||
Instances of QAction can be created by passing a parent QObject or
|
||||
by using one of the convenience functions of QMenu, QMenuBar or QToolBar.
|
||||
We create the actions that are in a menu as well as in a toolbar
|
||||
parented on the window to prevent ownership issues. For actions
|
||||
that are only in the menu, we use the convenience function
|
||||
QMenu::addAction(), which allows us to pass text, icon and the
|
||||
target object and its slot member function.
|
||||
|
||||
Creating toolbars is very similar to creating menus. The same
|
||||
actions that we put in the menus can be reused in the toolbars.
|
||||
After creating the action, we add it to the toolbar using
|
||||
QToolBar::addAction().
|
||||
|
||||
The code above contains one more idiom that must be explained.
|
||||
For some of the actions, we specify an icon as a QIcon to the
|
||||
QAction constructor. We use QIcon::fromTheme() to obtain
|
||||
the correct standard icon from the underlying window system.
|
||||
If that fails due to the platform not supporting it, we
|
||||
pass a file name as fallback. Here, the file name starts
|
||||
with \c{:}. Such file names aren't ordinary file names, but
|
||||
rather path in the executable's stored resources. We'll come back
|
||||
to this when we review the \c application.qrc file that's part of
|
||||
the project.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 23
|
||||
\snippet mainwindows/application/mainwindow.cpp 24
|
||||
|
||||
The \uicontrol{Edit|Cut} and \uicontrol{Edit|Copy} actions must be available
|
||||
only when the QPlainTextEdit contains selected text. We disable them
|
||||
by default and connect the QPlainTextEdit::copyAvailable() signal to
|
||||
the QAction::setEnabled() slot, ensuring that the actions are
|
||||
disabled when the text editor has no selection.
|
||||
|
||||
Just before we create the \uicontrol{Help} menu, we call
|
||||
QMenuBar::addSeparator(). This has no effect for most widget
|
||||
styles (e.g., Windows and \macos styles), but for some
|
||||
styles this makes sure that \uicontrol{Help} is pushed to the right
|
||||
side of the menu bar.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 32
|
||||
\snippet mainwindows/application/mainwindow.cpp 33
|
||||
|
||||
QMainWindow::statusBar() returns a pointer to the main window's
|
||||
QStatusBar widget. Like with \l{QMainWindow::menuBar()}, the
|
||||
widget is automatically created the first time the function is
|
||||
called.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 34
|
||||
\snippet mainwindows/application/mainwindow.cpp 36
|
||||
|
||||
The \c readSettings() function is called from the constructor to
|
||||
load the user's preferences and other application settings. The
|
||||
QSettings class provides a high-level interface for storing
|
||||
settings permanently on disk. On Windows, it uses the (in)famous
|
||||
Windows registry; on \macos, it uses the native XML-based
|
||||
CFPreferences API; on Unix/X11, it uses text files.
|
||||
|
||||
The QSettings constructor takes arguments that identify your
|
||||
company and the name of the product. This ensures that the
|
||||
settings for different applications are kept separately.
|
||||
|
||||
We use QSettings::value() to extract the value of the geometry setting.
|
||||
The second argument to QSettings::value() is
|
||||
optional and specifies a default value for the setting if there
|
||||
exists none. This value is used the first time the application is
|
||||
run.
|
||||
|
||||
We use QWidget::saveGeometry() and Widget::restoreGeometry() to
|
||||
save the position. They use an opaque QByteArray to store
|
||||
screen number, geometry and window state.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 37
|
||||
\snippet mainwindows/application/mainwindow.cpp 39
|
||||
|
||||
The \c writeSettings() function is called from \c closeEvent().
|
||||
Writing settings is similar to reading them, except simpler. The
|
||||
arguments to the QSettings constructor must be the same as in \c
|
||||
readSettings().
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 40
|
||||
\snippet mainwindows/application/mainwindow.cpp 41
|
||||
|
||||
The \c maybeSave() function is called to save pending changes. If
|
||||
there are pending changes, it pops up a QMessageBox giving the
|
||||
user to save the document. The options are QMessageBox::Yes,
|
||||
QMessageBox::No, and QMessageBox::Cancel. The \uicontrol{Yes} button is
|
||||
made the default button (the button that is invoked when the user
|
||||
presses \uicontrol{Return}) using the QMessageBox::Default flag; the
|
||||
\uicontrol{Cancel} button is made the escape button (the button that is
|
||||
invoked when the user presses \uicontrol{Esc}) using the
|
||||
QMessageBox::Escape flag.
|
||||
|
||||
The \c maybeSave() function returns \c true in all cases, except
|
||||
when the user clicks \uicontrol{Cancel} or saving the file fails.
|
||||
The caller must check the return value and stop whatever it was
|
||||
doing if the return value is \c false.
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 42
|
||||
\snippet mainwindows/application/mainwindow.cpp 43
|
||||
|
||||
In \c loadFile(), we use QFile and QTextStream to read in the
|
||||
data. The QFile object provides access to the bytes stored in a
|
||||
file.
|
||||
|
||||
We start by opening the file in read-only mode. The QFile::Text
|
||||
flag indicates that the file is a text file, not a binary file.
|
||||
On Unix and \macos, this makes no difference, but on Windows,
|
||||
it ensures that the "\\r\\n" end-of-line sequence is converted to
|
||||
"\\n" when reading.
|
||||
|
||||
If we successfully opened the file, we use a QTextStream object
|
||||
to read in the data. QTextStream automatically converts the 8-bit
|
||||
data into a Unicode QString and supports various encodings. If no
|
||||
encoding is specified, QTextStream assumes the file is encoded in
|
||||
UTF-8.
|
||||
|
||||
Since the call to QTextStream::readAll() might take some time, we
|
||||
set the cursor to be Qt::WaitCursor for the entire application
|
||||
while it goes on.
|
||||
|
||||
At the end, we call the private \c setCurrentFile() function,
|
||||
which we'll cover in a moment, and we display the string "File
|
||||
loaded" in the status bar for 2 seconds (2000 milliseconds).
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 44
|
||||
\snippet mainwindows/application/mainwindow.cpp 45
|
||||
|
||||
Saving a file is similar to loading one. We use QSaveFile to ensure
|
||||
all data are safely written and existing files are not damaged
|
||||
should writing fail.
|
||||
We use the QFile::Text flag to make sure that on Windows, "\\n"
|
||||
is converted into "\\r\\n" to conform to the Windows convention.
|
||||
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 46
|
||||
\snippet mainwindows/application/mainwindow.cpp 47
|
||||
|
||||
The \c setCurrentFile() function is called to reset the state of
|
||||
a few variables when a file is loaded or saved, or when the user
|
||||
starts editing a new file (in which case \c fileName is empty).
|
||||
We update the \c curFile variable, clear the
|
||||
QTextDocument::modified flag and the associated \c
|
||||
QWidget:windowModified flag, and update the window title to
|
||||
contain the new file name (or \c untitled.txt).
|
||||
|
||||
The \c strippedName() function call around \c curFile in the
|
||||
QWidget::setWindowTitle() call shortens the file name to exclude
|
||||
the path. Here's the function:
|
||||
|
||||
\snippet mainwindows/application/mainwindow.cpp 48
|
||||
\snippet mainwindows/application/mainwindow.cpp 49
|
||||
|
||||
\section1 The main() Function
|
||||
|
||||
The \c main() function for this application is typical of
|
||||
applications that contain one main window:
|
||||
|
||||
\snippet mainwindows/application/main.cpp 0
|
||||
|
||||
The main function uses QCommandLineParser to check whether some file
|
||||
argument was passed to the application and loads it via
|
||||
MainWindow::loadFile().
|
||||
|
||||
\section1 The Resource File
|
||||
|
||||
As you will probably recall, for some of the actions, we
|
||||
specified icons with file names starting with \c{:} and mentioned
|
||||
that such file names aren't ordinary file names, but path in the
|
||||
executable's stored resources. These resources are compiled
|
||||
|
||||
The resources associated with an application are specified in a
|
||||
\c .qrc file, an XML-based file format that lists files on the
|
||||
disk. Here's the \c application.qrc file that's used by the
|
||||
Application example:
|
||||
|
||||
\quotefile mainwindows/application/application.qrc
|
||||
|
||||
The \c .png files listed in the \c application.qrc file are files
|
||||
that are part of the Application example's source tree. Paths are
|
||||
relative to the directory where the \c application.qrc file is
|
||||
located (the \c mainwindows/application directory).
|
||||
|
||||
The resource file must be mentioned in the \c application.pro
|
||||
file so that \c qmake knows about it:
|
||||
|
||||
\snippet mainwindows/application/application.pro 0
|
||||
|
||||
\c qmake will produce make rules to generate a file called \c
|
||||
qrc_application.cpp that is linked into the application. This
|
||||
file contains all the data for the images and other resources as
|
||||
static C++ arrays of compressed binary data. See
|
||||
\l{resources.html}{The Qt Resource System} for more information
|
||||
about resources.
|
||||
*/
|
@ -1,7 +1,6 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_internal_add_example(application)
|
||||
qt_internal_add_example(dockwidgets)
|
||||
qt_internal_add_example(mainwindow)
|
||||
qt_internal_add_example(mdi)
|
||||
|
@ -9,7 +9,9 @@ build_all:!build_pass {
|
||||
CONFIG += release
|
||||
}
|
||||
|
||||
#! [qrc]
|
||||
RESOURCES += mainwindow.qrc
|
||||
#! [qrc]
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/mainwindow
|
||||
|
@ -1,6 +1,5 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = application \
|
||||
dockwidgets \
|
||||
SUBDIRS = dockwidgets \
|
||||
mainwindow \
|
||||
mdi \
|
||||
menus
|
||||
|
@ -52,15 +52,15 @@
|
||||
|
||||
Here's an example \c .qrc file:
|
||||
|
||||
\quotefile resource-system/application.qrc
|
||||
\quotefile resource-system/mainwindow.qrc
|
||||
|
||||
Each \c <file> element in the XML identifies a file in the application's
|
||||
source tree. The path is resolved relative to the directory containing
|
||||
the \c .qrc file.
|
||||
|
||||
The path is also used by default to identify the file's content at runtime.
|
||||
That is, the file \c copy.png will be available in the resource system as
|
||||
\c{:/images/copy.png} or \c{qrc:/images/copy.png}.
|
||||
That is, the file \c titlebarLeft.png will be available in the resource system as
|
||||
\c{:/res/titlebarLeft.png} or \c{qrc:/res/titlebarLeft.png}.
|
||||
To override this default run-time name, see \l{Prefixes} and \l{Aliases}.
|
||||
|
||||
\e{Qt Creator}, \e{Qt Design Studio}, \QD, and \e{Qt Visual Studio Tools}
|
||||
@ -102,22 +102,16 @@
|
||||
variable. If you add a \c .qrc file path to the variable, the listed
|
||||
resource files will be embedded into the generated library or executable:
|
||||
|
||||
\snippet resource-system/application.pro 0
|
||||
|
||||
For simple applications, it is also possible to let qmake generate the
|
||||
\c .qrc file for you, avoiding the need for an additional file to be
|
||||
maintained:
|
||||
|
||||
\snippet resource-system/application.pro 1
|
||||
\snippet resource-system/mainwindow.pro qrc
|
||||
|
||||
This creates a resource of several \c{.png} files, that are addressable
|
||||
like this: \c{":/images/copy.png"}.
|
||||
like this: \c{":/res/titlebarLeft.png"}.
|
||||
|
||||
If the directory layout of the files you want to embed into the resource
|
||||
doesn't match the expectations of the application, you can specify
|
||||
\c{resources.base}. \c base is a path prefix that denotes the root point of
|
||||
the file's alias. In the example above, if \c{resources.base} is set to
|
||||
\c{"images"}, then \c{copy.png} is addressable as \c{":/copy.png"}.
|
||||
\c{"res"}, then \c{titlebarLeft.png} is addressable as \c{":/titlebarLeft.png"}.
|
||||
|
||||
\section1 Runtime API
|
||||
|
||||
@ -136,7 +130,7 @@
|
||||
|
||||
\snippet resource-system/main.cpp url
|
||||
|
||||
See the \l{mainwindows/application}{Application} example for an actual
|
||||
See the \l{mainwindows/mainwindow}{Mainwindow} example for an actual
|
||||
application that uses Qt's resource system to store its icons.
|
||||
|
||||
\section1 Advanced Topics
|
||||
@ -216,14 +210,7 @@
|
||||
resource file's content and metadata is then done after the compilation and
|
||||
linking phase, through another rcc call.
|
||||
|
||||
For qmake, this is enabled by adding \c resources_big to the \c CONFIG
|
||||
variable:
|
||||
|
||||
\snippet resource-system/application.pro 2
|
||||
|
||||
For CMake, you need to use the \l{qt_add_big_resources} function:
|
||||
|
||||
\snippet resource-system/CMakeLists.txt qt_add_big_resources
|
||||
For CMake, you need to use the \l{qt_add_big_resources} function.
|
||||
|
||||
\section2 External Resource Files
|
||||
|
||||
@ -251,13 +238,13 @@
|
||||
resource compiler \l rcc:
|
||||
|
||||
\code
|
||||
rcc -g python application.qrc > application_rc.py
|
||||
rcc -g python mainwindow.qrc > mainwindow_rc.py
|
||||
\endcode
|
||||
|
||||
The module can then be imported in the application:
|
||||
|
||||
\code
|
||||
import application_rc.py
|
||||
import mainwindow_rc.py
|
||||
\endcode
|
||||
|
||||
\section2 Compression
|
||||
|
@ -1837,10 +1837,6 @@ Q_IMPL_EVENT_COMMON(QResizeEvent)
|
||||
special handling, you should reimplement the event handler and
|
||||
ignore() the event.
|
||||
|
||||
The \l{mainwindows/application#close event handler}{closeEvent() in the
|
||||
Application example} shows a close event handler that
|
||||
asks whether to save a document before closing.
|
||||
|
||||
If you want the widget to be deleted when it is closed, create it
|
||||
with the Qt::WA_DeleteOnClose flag. This is very useful for
|
||||
independent top-level windows in a multi-window application.
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 852 B After Width: | Height: | Size: 852 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@ -1,7 +1,6 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
//! [0]
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
@ -29,4 +28,3 @@ int main(int argc, char *argv[])
|
||||
mainWin.show();
|
||||
return app.exec();
|
||||
}
|
||||
//! [0]
|
@ -1,16 +1,12 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
//! [0]
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "mainwindow.h"
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
MainWindow::MainWindow()
|
||||
: textEdit(new QPlainTextEdit)
|
||||
//! [1] //! [2]
|
||||
{
|
||||
setCentralWidget(textEdit);
|
||||
|
||||
@ -30,11 +26,8 @@ MainWindow::MainWindow()
|
||||
setCurrentFile(QString());
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
//! [3] //! [4]
|
||||
{
|
||||
if (maybeSave()) {
|
||||
writeSettings();
|
||||
@ -43,22 +36,16 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
void MainWindow::newFile()
|
||||
//! [5] //! [6]
|
||||
{
|
||||
if (maybeSave()) {
|
||||
textEdit->clear();
|
||||
setCurrentFile(QString());
|
||||
}
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
void MainWindow::open()
|
||||
//! [7] //! [8]
|
||||
{
|
||||
if (maybeSave()) {
|
||||
QString fileName = QFileDialog::getOpenFileName(this);
|
||||
@ -66,11 +53,8 @@ void MainWindow::open()
|
||||
loadFile(fileName);
|
||||
}
|
||||
}
|
||||
//! [8]
|
||||
|
||||
//! [9]
|
||||
bool MainWindow::save()
|
||||
//! [9] //! [10]
|
||||
{
|
||||
if (curFile.isEmpty()) {
|
||||
return saveAs();
|
||||
@ -78,11 +62,8 @@ bool MainWindow::save()
|
||||
return saveFile(curFile);
|
||||
}
|
||||
}
|
||||
//! [10]
|
||||
|
||||
//! [11]
|
||||
bool MainWindow::saveAs()
|
||||
//! [11] //! [12]
|
||||
{
|
||||
QFileDialog dialog(this);
|
||||
dialog.setWindowModality(Qt::WindowModal);
|
||||
@ -91,30 +72,21 @@ bool MainWindow::saveAs()
|
||||
return false;
|
||||
return saveFile(dialog.selectedFiles().first());
|
||||
}
|
||||
//! [12]
|
||||
|
||||
//! [13]
|
||||
void MainWindow::about()
|
||||
//! [13] //! [14]
|
||||
{
|
||||
QMessageBox::about(this, tr("About Application"),
|
||||
tr("The <b>Application</b> example demonstrates how to "
|
||||
"write modern GUI applications using Qt, with a menu bar, "
|
||||
"toolbars, and a status bar."));
|
||||
}
|
||||
//! [14]
|
||||
|
||||
//! [15]
|
||||
void MainWindow::documentWasModified()
|
||||
//! [15] //! [16]
|
||||
{
|
||||
setWindowModified(textEdit->document()->isModified());
|
||||
}
|
||||
//! [16]
|
||||
|
||||
//! [17]
|
||||
void MainWindow::createActions()
|
||||
//! [17] //! [18]
|
||||
{
|
||||
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
@ -127,7 +99,6 @@ void MainWindow::createActions()
|
||||
fileMenu->addAction(newAct);
|
||||
fileToolBar->addAction(newAct);
|
||||
|
||||
//! [19]
|
||||
const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png"));
|
||||
QAction *openAct = new QAction(openIcon, tr("&Open..."), this);
|
||||
openAct->setShortcuts(QKeySequence::Open);
|
||||
@ -135,7 +106,6 @@ void MainWindow::createActions()
|
||||
connect(openAct, &QAction::triggered, this, &MainWindow::open);
|
||||
fileMenu->addAction(openAct);
|
||||
fileToolBar->addAction(openAct);
|
||||
//! [18] //! [19]
|
||||
|
||||
const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png"));
|
||||
QAction *saveAct = new QAction(saveIcon, tr("&Save"), this);
|
||||
@ -150,24 +120,19 @@ void MainWindow::createActions()
|
||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
||||
saveAsAct->setStatusTip(tr("Save the document under a new name"));
|
||||
|
||||
//! [20]
|
||||
|
||||
fileMenu->addSeparator();
|
||||
|
||||
const QIcon exitIcon = QIcon::fromTheme("application-exit");
|
||||
QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close);
|
||||
exitAct->setShortcuts(QKeySequence::Quit);
|
||||
//! [20]
|
||||
exitAct->setStatusTip(tr("Exit the application"));
|
||||
|
||||
//! [21]
|
||||
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
||||
QToolBar *editToolBar = addToolBar(tr("Edit"));
|
||||
//!
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png"));
|
||||
QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this);
|
||||
//! [21]
|
||||
cutAct->setShortcuts(QKeySequence::Cut);
|
||||
cutAct->setStatusTip(tr("Cut the current selection's contents to the "
|
||||
"clipboard"));
|
||||
@ -201,34 +166,23 @@ void MainWindow::createActions()
|
||||
QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||
aboutAct->setStatusTip(tr("Show the application's About box"));
|
||||
|
||||
//! [22]
|
||||
|
||||
QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
|
||||
aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
|
||||
//! [22]
|
||||
|
||||
//! [23]
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
cutAct->setEnabled(false);
|
||||
//! [23] //! [24]
|
||||
copyAct->setEnabled(false);
|
||||
connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
|
||||
connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
|
||||
#endif // !QT_NO_CLIPBOARD
|
||||
}
|
||||
//! [24]
|
||||
|
||||
//! [32]
|
||||
void MainWindow::createStatusBar()
|
||||
//! [32] //! [33]
|
||||
{
|
||||
statusBar()->showMessage(tr("Ready"));
|
||||
}
|
||||
//! [33]
|
||||
|
||||
//! [34] //! [35]
|
||||
void MainWindow::readSettings()
|
||||
//! [34] //! [36]
|
||||
{
|
||||
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
|
||||
@ -241,20 +195,14 @@ void MainWindow::readSettings()
|
||||
restoreGeometry(geometry);
|
||||
}
|
||||
}
|
||||
//! [35] //! [36]
|
||||
|
||||
//! [37] //! [38]
|
||||
void MainWindow::writeSettings()
|
||||
//! [37] //! [39]
|
||||
{
|
||||
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
settings.setValue("geometry", saveGeometry());
|
||||
}
|
||||
//! [38] //! [39]
|
||||
|
||||
//! [40]
|
||||
bool MainWindow::maybeSave()
|
||||
//! [40] //! [41]
|
||||
{
|
||||
if (!textEdit->document()->isModified())
|
||||
return true;
|
||||
@ -273,11 +221,8 @@ bool MainWindow::maybeSave()
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//! [41]
|
||||
|
||||
//! [42]
|
||||
void MainWindow::loadFile(const QString &fileName)
|
||||
//! [42] //! [43]
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
@ -299,11 +244,8 @@ void MainWindow::loadFile(const QString &fileName)
|
||||
setCurrentFile(fileName);
|
||||
statusBar()->showMessage(tr("File loaded"), 2000);
|
||||
}
|
||||
//! [43]
|
||||
|
||||
//! [44]
|
||||
bool MainWindow::saveFile(const QString &fileName)
|
||||
//! [44] //! [45]
|
||||
{
|
||||
QString errorMessage;
|
||||
|
||||
@ -331,11 +273,8 @@ bool MainWindow::saveFile(const QString &fileName)
|
||||
statusBar()->showMessage(tr("File saved"), 2000);
|
||||
return true;
|
||||
}
|
||||
//! [45]
|
||||
|
||||
//! [46]
|
||||
void MainWindow::setCurrentFile(const QString &fileName)
|
||||
//! [46] //! [47]
|
||||
{
|
||||
curFile = fileName;
|
||||
textEdit->document()->setModified(false);
|
||||
@ -346,15 +285,12 @@ void MainWindow::setCurrentFile(const QString &fileName)
|
||||
shownName = "untitled.txt";
|
||||
setWindowFilePath(shownName);
|
||||
}
|
||||
//! [47]
|
||||
|
||||
//! [48]
|
||||
QString MainWindow::strippedName(const QString &fullFileName)
|
||||
//! [48] //! [49]
|
||||
{
|
||||
return QFileInfo(fullFileName).fileName();
|
||||
}
|
||||
//! [49]
|
||||
|
||||
#ifndef QT_NO_SESSIONMANAGER
|
||||
void MainWindow::commitData(QSessionManager &manager)
|
||||
{
|
@ -13,7 +13,6 @@ class QPlainTextEdit;
|
||||
class QSessionManager;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -50,6 +49,5 @@ private:
|
||||
QPlainTextEdit *textEdit;
|
||||
QString curFile;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|