Merge pull request #3937 from akohlmey/collected-small-changes
Collected small changes and fixes
This commit is contained in:
@ -702,11 +702,15 @@ Prerequisites and portability
|
||||
LAMMPS GUI is programmed in C++ based on the C++11 standard and using
|
||||
the `Qt GUI framework <https://www.qt.io/product/framework>`_.
|
||||
Currently, Qt version 5.12 or later is required; Qt 5.15LTS is
|
||||
recommended; Qt 6.x not (yet) supported. Building LAMMPS with CMake is
|
||||
required. The LAMMPS GUI has been successfully compiled and tested on:
|
||||
recommended; support for Qt version 6.x is under active development and
|
||||
thus far only tested with Qt 6.5LTS on Linux. Building LAMMPS with
|
||||
CMake is required.
|
||||
|
||||
The LAMMPS GUI has been successfully compiled and tested on:
|
||||
|
||||
- Ubuntu Linux 20.04LTS x86_64 using GCC 9, Qt version 5.12
|
||||
- Fedora Linux 38 x86\_64 using GCC 13 and Clang 16, Qt version 5.15LTS
|
||||
- Fedora Linux 38 x86\_64 using GCC 13, Qt version 6.5LTS
|
||||
- Apple macOS 12 (Monterey) and macOS 13 (Ventura) with Xcode on arm64 and x86\_64, Qt version 5.15LTS
|
||||
- Windows 10 and 11 x86_64 with Visual Studio 2022 and Visual C++ 14.36, Qt version 5.15LTS
|
||||
- Windows 10 and 11 x86_64 with MinGW / GCC 10.0 cross-compiler on Fedora 38, Qt version 5.15LTS
|
||||
@ -717,7 +721,7 @@ required. The LAMMPS GUI has been successfully compiled and tested on:
|
||||
Pre-compiled executables
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pre-compiled LAMMPS executables including the GUI are currently
|
||||
Pre-compiled LAMMPS executable packages that include the GUI are currently
|
||||
available from https://download.lammps.org/static or
|
||||
https://github.com/lammps/lammps/releases. You can unpack the archives
|
||||
(or mount the macOS disk image) and run the GUI directly in place. The
|
||||
@ -742,7 +746,10 @@ stored in a location where CMake can find them without additional help.
|
||||
Otherwise, the location of the Qt library installation must be indicated
|
||||
by setting ``-D Qt5_DIR=/path/to/qt5/lib/cmake/Qt5``, which is a path to
|
||||
a folder inside the Qt installation that contains the file
|
||||
``Qt5Config.cmake``.
|
||||
``Qt5Config.cmake``. Similarly, for Qt6 the location of the Qt library
|
||||
installation can be indicated by setting ``-D Qt6_DIR=/path/to/qt6/lib/cmake/Qt6``,
|
||||
if necessary. When both, Qt5 and Qt6 are available, Qt6 will be preferred
|
||||
unless ``-D LAMMPS_GUI_USE_QT5=yes`` is set.
|
||||
|
||||
It should be possible to build the LAMMPS GUI as a standalone
|
||||
compilation (e.g. when LAMMPS has been compiled with traditional make),
|
||||
|
||||
@ -71,14 +71,15 @@ imbue the SRD particles with fluid-like properties, including an
|
||||
effective viscosity. Thus simulations with large solute particles can
|
||||
be run more quickly, to measure solute properties like diffusivity
|
||||
and viscosity in a background fluid. The usual LAMMPS fixes for such
|
||||
simulations, such as :doc:`fix deform <fix_deform>`, :doc:`fix viscosity <fix_viscosity>`, and :doc:`fix nvt/sllod <fix_nvt_sllod>`,
|
||||
simulations, such as :doc:`fix deform <fix_deform>`,
|
||||
:doc:`fix viscosity <fix_viscosity>`, and :doc:`fix nvt/sllod <fix_nvt_sllod>`,
|
||||
can be used in conjunction with the SRD model.
|
||||
|
||||
For more details on how the SRD model is implemented in LAMMPS, :ref:`this paper <Petersen1>` describes the implementation and usage of pure SRD
|
||||
fluids. :ref:`This paper <Lechman>`, which is nearly complete, describes
|
||||
the implementation and usage of mixture systems (solute particles in
|
||||
an SRD fluid). See the examples/srd directory for sample input
|
||||
scripts using SRD particles in both settings.
|
||||
For more details on how the SRD model is implemented in LAMMPS,
|
||||
:ref:`(Petersen) <Petersen1>` describes the implementation and usage of
|
||||
pure SRD fluids. See the ``examples/srd`` directory for sample input
|
||||
scripts using SRD particles for that and for mixture systems (solute
|
||||
particles in an SRD fluid).
|
||||
|
||||
This fix does two things:
|
||||
|
||||
@ -357,28 +358,28 @@ These are the 12 quantities. All are values for the current timestep,
|
||||
except for quantity 5 and the last three, each of which are
|
||||
cumulative quantities since the beginning of the run.
|
||||
|
||||
* (1) # of SRD/big collision checks performed
|
||||
* (2) # of SRDs which had a collision
|
||||
* (3) # of SRD/big collisions (including multiple bounces)
|
||||
* (4) # of SRD particles inside a big particle
|
||||
* (5) # of SRD particles whose velocity was rescaled to be < Vmax
|
||||
* (6) # of bins for collision searching
|
||||
* (7) # of bins for SRD velocity rotation
|
||||
* (8) # of bins in which SRD temperature was computed
|
||||
* (9) SRD temperature
|
||||
* (10) # of SRD particles which have undergone max # of bounces
|
||||
* (11) max # of bounces any SRD particle has had in a single step
|
||||
* (12) # of reneighborings due to SRD particles moving too far
|
||||
(1) # of SRD/big collision checks performed
|
||||
(2) # of SRDs which had a collision
|
||||
(3) # of SRD/big collisions (including multiple bounces)
|
||||
(4) # of SRD particles inside a big particle
|
||||
(5) # of SRD particles whose velocity was rescaled to be < Vmax
|
||||
(6) # of bins for collision searching
|
||||
(7) # of bins for SRD velocity rotation
|
||||
(8) # of bins in which SRD temperature was computed
|
||||
(9) SRD temperature
|
||||
(10) # of SRD particles which have undergone max # of bounces
|
||||
(11) max # of bounces any SRD particle has had in a single step
|
||||
(12) # of reneighborings due to SRD particles moving too far
|
||||
|
||||
No parameter of this fix can be used with the *start/stop* keywords of
|
||||
the :doc:`run <run>` command. This fix is not invoked during :doc:`energy minimization <minimize>`.
|
||||
the :doc:`run <run>` command. This fix is not invoked during
|
||||
:doc:`energy minimization <minimize>`.
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
|
||||
This command can only be used if LAMMPS was built with the SRD
|
||||
package. See the :doc:`Build package <Build_package>` doc
|
||||
page for more info.
|
||||
This command can only be used if LAMMPS was built with the SRD package.
|
||||
See the :doc:`Build package <Build_package>` doc page for more info.
|
||||
|
||||
Related commands
|
||||
""""""""""""""""
|
||||
@ -403,7 +404,3 @@ no, and rescale = yes.
|
||||
|
||||
**(Petersen)** Petersen, Lechman, Plimpton, Grest, in' t Veld, Schunk, J
|
||||
Chem Phys, 132, 174106 (2010).
|
||||
|
||||
.. _Lechman:
|
||||
|
||||
**(Lechman)** Lechman, et al, in preparation (2010).
|
||||
|
||||
@ -22,12 +22,12 @@ Examples
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
pair_style hybrid/overlay ilp/tmd 16.0 1
|
||||
pair_coeff * * ilp/tmd TMD.ILP Mo S S
|
||||
pair_coeff * * ilp/tmd MoS2.ILP Mo S S
|
||||
|
||||
pair_style hybrid/overlay sw/mod sw/mod ilp/tmd 16.0
|
||||
pair_coeff * * sw/mod 1 tmd.sw.mod Mo S S NULL NULL NULL
|
||||
pair_coeff * * sw/mod 2 tmd.sw.mod NULL NULL NULL Mo S S
|
||||
pair_coeff * * ilp/tmd TMD.ILP Mo S S Mo S S
|
||||
pair_coeff * * ilp/tmd MoS2.ILP Mo S S Mo S S
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
@ -69,7 +69,7 @@ calculating the normals.
|
||||
each atom `i`, its six nearest neighboring atoms belonging to the same
|
||||
sub-layer are chosen to define the normal vector `{\bf n}_i`.
|
||||
|
||||
The parameter file (e.g. TMD.ILP), is intended for use with *metal*
|
||||
The parameter file (e.g. MoS2.ILP), is intended for use with *metal*
|
||||
:doc:`units <units>`, with energies in meV. Two additional parameters,
|
||||
*S*, and *rcut* are included in the parameter file. *S* is designed to
|
||||
facilitate scaling of energies. *rcut* is designed to build the neighbor
|
||||
@ -77,7 +77,7 @@ list for calculating the normals for each atom pair.
|
||||
|
||||
.. note::
|
||||
|
||||
The parameters presented in the parameter file (e.g. TMD.ILP),
|
||||
The parameters presented in the parameter file (e.g. MoS2.ILP),
|
||||
are fitted with taper function by setting the cutoff equal to 16.0
|
||||
Angstrom. Using different cutoff or taper function should be careful.
|
||||
These parameters provide a good description in both short- and long-range
|
||||
@ -133,10 +133,10 @@ if LAMMPS was built with that package. See the :doc:`Build package
|
||||
This pair style requires the newton setting to be *on* for pair
|
||||
interactions.
|
||||
|
||||
The TMD.ILP potential file provided with LAMMPS (see the potentials
|
||||
The MoS2.ILP potential file provided with LAMMPS (see the potentials
|
||||
directory) are parameterized for *metal* units. You can use this
|
||||
potential with any LAMMPS units, but you would need to create your own
|
||||
custom TMD.ILP potential file with coefficients listed in the appropriate
|
||||
custom MoS2.ILP potential file with coefficients listed in the appropriate
|
||||
units, if your simulation does not use *metal* units.
|
||||
|
||||
Related commands
|
||||
|
||||
@ -43,22 +43,22 @@ Examples
|
||||
Description
|
||||
"""""""""""
|
||||
|
||||
Style *reaxff* computes the ReaxFF potential of van Duin, Goddard and
|
||||
co-workers. ReaxFF uses distance-dependent bond-order functions to
|
||||
Pair style *reaxff* computes the ReaxFF potential of van Duin, Goddard
|
||||
and co-workers. ReaxFF uses distance-dependent bond-order functions to
|
||||
represent the contributions of chemical bonding to the potential
|
||||
energy. There is more than one version of ReaxFF. The version
|
||||
energy. There is more than one version of ReaxFF. The version
|
||||
implemented in LAMMPS uses the functional forms documented in the
|
||||
supplemental information of the following paper:
|
||||
:ref:`(Chenoweth et al., 2008) <Chenoweth_20082>`. The version integrated
|
||||
into LAMMPS matches the version of ReaxFF From Summer 2010. For more
|
||||
technical details about the pair reaxff implementation of ReaxFF, see
|
||||
the :ref:`(Aktulga) <Aktulga>` paper. The *reaxff* style was initially
|
||||
implemented as a stand-alone C code and is now converted to C++ and
|
||||
integrated into LAMMPS as a package.
|
||||
:ref:`(Chenoweth et al., 2008) <Chenoweth_20082>` and matches the
|
||||
version of the reference ReaxFF implementation from Summer 2010. For
|
||||
more technical details about the implementation of ReaxFF in pair style
|
||||
*reaxff*, see the :ref:`(Aktulga) <Aktulga>` paper. The *reaxff* style
|
||||
was initially implemented as a stand-alone C code and is now converted
|
||||
to C++ and integrated into LAMMPS as a package.
|
||||
|
||||
The *reaxff/kk* style is a Kokkos version of the ReaxFF potential that
|
||||
is derived from the *reaxff* style. The Kokkos version can run on GPUs
|
||||
and can also use OpenMP multithreading. For more information about the
|
||||
is derived from the *reaxff* style. The Kokkos version can run on GPUs
|
||||
and can also use OpenMP multithreading. For more information about the
|
||||
Kokkos package, see :doc:`Packages details <Packages_details>` and
|
||||
:doc:`Speed kokkos <Speed_kokkos>` doc pages. One important
|
||||
consideration when using the *reaxff/kk* style is the choice of either
|
||||
|
||||
@ -32,6 +32,7 @@ namespace LAMMPS_NS {
|
||||
// get access to number of threads and per-thread data structures via FixOMP
|
||||
#define NPAIR_OMP_INIT \
|
||||
const int nthreads = comm->nthreads; \
|
||||
omp_set_num_threads(nthreads); \
|
||||
const int ifix = modify->find_fix("package_omp")
|
||||
|
||||
// get thread id and then assign each thread a fixed chunk of atoms
|
||||
|
||||
@ -27,8 +27,8 @@ using namespace LAMMPS_NS;
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
ComputeMSDChunk::ComputeMSDChunk(LAMMPS *lmp, int narg, char **arg) :
|
||||
ComputeChunk(lmp, narg, arg), id_fix(nullptr), massproc(nullptr), masstotal(nullptr),
|
||||
com(nullptr), comall(nullptr), msd(nullptr)
|
||||
ComputeChunk(lmp, narg, arg), id_fix(nullptr), fix(nullptr), massproc(nullptr),
|
||||
masstotal(nullptr), com(nullptr), comall(nullptr), msd(nullptr)
|
||||
{
|
||||
if (narg != 4) error->all(FLERR, "Illegal compute msd/chunk command");
|
||||
|
||||
@ -196,6 +196,12 @@ void ComputeMSDChunk::compute_array()
|
||||
void ComputeMSDChunk::allocate()
|
||||
{
|
||||
ComputeChunk::allocate();
|
||||
memory->destroy(massproc);
|
||||
memory->destroy(masstotal);
|
||||
memory->destroy(com);
|
||||
memory->destroy(comall);
|
||||
memory->destroy(msd);
|
||||
|
||||
memory->create(massproc, nchunk, "msd/chunk:massproc");
|
||||
memory->create(masstotal, nchunk, "msd/chunk:masstotal");
|
||||
memory->create(com, nchunk, 3, "msd/chunk:com");
|
||||
|
||||
@ -11,6 +11,42 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
option(LAMMPS_GUI_USE_PLUGIN "Load LAMMPS library dynamically at runtime" OFF)
|
||||
mark_as_advanced(LAMMPS_GUI_USE_PLUGIN)
|
||||
option(LAMMPS_GUI_USE_QT5 "Prefer using Qt5 over Qt6" OFF)
|
||||
|
||||
include(CheckIncludeFileCXX)
|
||||
# helper function to check for usable omp.h header
|
||||
function(check_omp_h_include)
|
||||
find_package(OpenMP COMPONENTS CXX QUIET)
|
||||
if(OpenMP_CXX_FOUND)
|
||||
set(CMAKE_REQUIRED_FLAGS ${OpenMP_CXX_FLAGS})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OpenMP_CXX_INCLUDE_DIRS})
|
||||
set(CMAKE_REQUIRED_LINK_OPTIONS ${OpenMP_CXX_FLAGS})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OpenMP_CXX_LIBRARIES})
|
||||
check_include_file_cxx(omp.h _have_omp_h)
|
||||
else()
|
||||
set(_have_omp_h FALSE)
|
||||
endif()
|
||||
set(HAVE_OMP_H_INCLUDE ${_have_omp_h} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# detect if we may enable OpenMP support by default
|
||||
set(BUILD_OMP_DEFAULT OFF)
|
||||
find_package(OpenMP COMPONENTS CXX QUIET)
|
||||
if(OpenMP_CXX_FOUND)
|
||||
check_omp_h_include()
|
||||
if(HAVE_OMP_H_INCLUDE)
|
||||
set(BUILD_OMP_DEFAULT ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(BUILD_OMP "Build with OpenMP support" ${BUILD_OMP_DEFAULT})
|
||||
if(BUILD_OMP)
|
||||
find_package(OpenMP COMPONENTS CXX REQUIRED)
|
||||
check_omp_h_include()
|
||||
if(NOT HAVE_OMP_H_INCLUDE)
|
||||
message(FATAL_ERROR "Cannot find the 'omp.h' header file required for full OpenMP support")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# checks
|
||||
# when this file is included as subdirectory in the LAMMPS build, many settings are directly imported
|
||||
@ -73,7 +109,15 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
endif()
|
||||
|
||||
# we require Qt 5 and at least version 5.12 at that.
|
||||
find_package(Qt5 5.12 REQUIRED COMPONENTS Widgets Charts)
|
||||
if(NOT LAMMPS_GUI_USE_QT5)
|
||||
find_package(Qt6 6.2 COMPONENTS Widgets Charts)
|
||||
endif()
|
||||
if(NOT Qt6_FOUND)
|
||||
find_package(Qt5 5.12 REQUIRED COMPONENTS Widgets Charts)
|
||||
set(QT_VERSION_MAJOR "5")
|
||||
else()
|
||||
set(QT_VERSION_MAJOR "6")
|
||||
endif()
|
||||
|
||||
set(PROJECT_SOURCES
|
||||
main.cpp
|
||||
@ -105,7 +149,11 @@ set(PROJECT_SOURCES
|
||||
${PLUGIN_LOADER_SRC}
|
||||
${ICON_RC_FILE}
|
||||
)
|
||||
qt5_add_resources(PROJECT_SOURCES lammpsgui.qrc)
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt6_add_resources(PROJECT_SOURCES lammpsgui.qrc)
|
||||
else()
|
||||
qt5_add_resources(PROJECT_SOURCES lammpsgui.qrc)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(MACOSX_ICON_FILE ${LAMMPS_DIR}/cmake/packaging/lammps.icns)
|
||||
@ -113,10 +161,22 @@ if(APPLE)
|
||||
set(MACOSX_BACKGROUND_FILE ${LAMMPS_DIR}/cmake/packaging/LAMMPS_DMG_Background.png)
|
||||
endif()
|
||||
|
||||
add_executable(lammps-gui
|
||||
${MACOSX_ICON_FILE}
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_add_executable(lammps-gui
|
||||
MANUAL_FINALIZATION
|
||||
${MACOSX_ICON_FILE}
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
else()
|
||||
add_executable(lammps-gui
|
||||
${MACOSX_ICON_FILE}
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_finalize_executable(lammps-gui)
|
||||
endif()
|
||||
|
||||
# compilation settings
|
||||
if(LAMMPS_GUI_USE_PLUGIN)
|
||||
@ -128,7 +188,7 @@ else()
|
||||
endif()
|
||||
target_include_directories(lammps-gui PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_definitions(lammps-gui PRIVATE LAMMPS_GUI_VERSION="${PROJECT_VERSION}")
|
||||
target_link_libraries(lammps-gui PRIVATE Qt5::Widgets Qt5::Charts)
|
||||
target_link_libraries(lammps-gui PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${VERSION_MAJOR}::Charts)
|
||||
if(BUILD_OMP)
|
||||
find_package(OpenMP COMPONENTS CXX REQUIRED)
|
||||
target_link_libraries(lammps-gui PRIVATE OpenMP::OpenMP_CXX)
|
||||
@ -209,7 +269,7 @@ elseif((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING)
|
||||
COMMENT "Create zip file with windows binaries"
|
||||
BYPRODUCT LAMMPS-Win10-amd64.zip
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND NOT LAMMPS_GUI_USE_PLUGIN)
|
||||
install(TARGETS lammps-gui DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/lammps-gui.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications/)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/lammps-input.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages/)
|
||||
|
||||
@ -23,7 +23,6 @@ LAMMPS-GUI TODO list:
|
||||
|
||||
# Long term ideas (v2.x)
|
||||
- rewrite entire application to build the App and its layout manually
|
||||
- port to Qt6 (with compatibility to Qt5?)
|
||||
- also a rewrite should establish consistent naming conventions. now we have a mix of LAMMPS style, Qt style, and others.
|
||||
- add option to attach a debugger to the running program (highly non-portable, need customization support in preferences)
|
||||
- write a "wizard" dialog that can be used for beginners to create an input file template for a few typical use scenarios
|
||||
|
||||
@ -15,11 +15,20 @@
|
||||
|
||||
#include "lammpsgui.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QKeySequence>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLineSeries>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QSpacerItem>
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
using namespace QtCharts;
|
||||
@ -53,13 +62,13 @@ ChartWindow::ChartWindow(const QString &_filename, QWidget *parent) :
|
||||
file->addSeparator();
|
||||
stopAct = file->addAction("Stop &Run", this, &ChartWindow::stop_run);
|
||||
stopAct->setIcon(QIcon(":/icons/process-stop.png"));
|
||||
stopAct->setShortcut(QKeySequence::fromString("Ctrl+/"));
|
||||
stopAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Slash));
|
||||
closeAct = file->addAction("&Close", this, &QWidget::close);
|
||||
closeAct->setIcon(QIcon(":/icons/window-close.png"));
|
||||
closeAct->setShortcut(QKeySequence::fromString("Ctrl+W"));
|
||||
closeAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_W));
|
||||
quitAct = file->addAction("&Quit", this, &ChartWindow::quit);
|
||||
quitAct->setIcon(QIcon(":/icons/application-exit.png"));
|
||||
quitAct->setShortcut(QKeySequence::fromString("Ctrl+Q"));
|
||||
quitAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
|
||||
auto *layout = new QVBoxLayout;
|
||||
layout->addLayout(top);
|
||||
setLayout(layout);
|
||||
@ -76,7 +85,10 @@ int ChartWindow::get_step() const
|
||||
{
|
||||
if (charts.size() > 0) {
|
||||
auto *v = charts[0];
|
||||
return (int)v->get_step(v->get_count() - 1);
|
||||
if (v)
|
||||
return (int)v->get_step(v->get_count() - 1);
|
||||
else
|
||||
return -1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@ -115,10 +127,10 @@ void ChartWindow::add_data(int step, double data, int index)
|
||||
|
||||
void ChartWindow::quit()
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
main->quit();
|
||||
if (main) main->quit();
|
||||
}
|
||||
|
||||
void ChartWindow::reset_zoom()
|
||||
@ -129,10 +141,10 @@ void ChartWindow::reset_zoom()
|
||||
|
||||
void ChartWindow::stop_run()
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
main->stop_run();
|
||||
if (main) main->stop_run();
|
||||
}
|
||||
|
||||
void ChartWindow::saveAs()
|
||||
@ -288,7 +300,7 @@ void ChartViewer::add_data(int step, double data)
|
||||
if (last_step < step) {
|
||||
last_step = step;
|
||||
series->append(step, data);
|
||||
auto points = series->pointsVector();
|
||||
auto points = series->points();
|
||||
|
||||
qreal xmin = 1.0e100;
|
||||
qreal xmax = -1.0e100;
|
||||
@ -309,7 +321,7 @@ void ChartViewer::add_data(int step, double data)
|
||||
|
||||
void ChartViewer::reset_zoom()
|
||||
{
|
||||
auto points = series->pointsVector();
|
||||
auto points = series->points();
|
||||
|
||||
qreal xmin = 1.0e100;
|
||||
qreal xmax = -1.0e100;
|
||||
|
||||
@ -14,16 +14,17 @@
|
||||
#ifndef CHARTVIEWER_H
|
||||
#define CHARTVIEWER_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QtCharts>
|
||||
|
||||
class QAction;
|
||||
class QMenuBar;
|
||||
class QMenu;
|
||||
class QComboBox;
|
||||
namespace QtCharts {
|
||||
class ChartViewer;
|
||||
}
|
||||
|
||||
class ChartWindow : public QWidget {
|
||||
Q_OBJECT
|
||||
@ -64,12 +65,18 @@ private:
|
||||
QAction *closeAct, *stopAct, *quitAct;
|
||||
|
||||
QString filename;
|
||||
QList<ChartViewer *> charts;
|
||||
QList<QtCharts::ChartViewer *> charts;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
class ChartViewer : public QtCharts::QChartView {
|
||||
#include <QChart>
|
||||
#include <QChartView>
|
||||
#include <QLineSeries>
|
||||
#include <QValueAxis>
|
||||
|
||||
namespace QtCharts {
|
||||
class ChartViewer : public QChartView {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -81,16 +88,17 @@ public:
|
||||
int get_index() const { return index; };
|
||||
int get_count() const { return series->count(); }
|
||||
const char *get_title() const { return series->name().toLocal8Bit(); }
|
||||
double get_step(int index) const { return series->at(index).x(); }
|
||||
double get_data(int index) const { return series->at(index).y(); }
|
||||
double get_step(int index) const { return (index < 0) ? 0.0 : series->at(index).x(); }
|
||||
double get_data(int index) const { return (index < 0) ? 0.0 : series->at(index).y(); }
|
||||
|
||||
private:
|
||||
int last_step, index;
|
||||
QtCharts::QChart *chart;
|
||||
QtCharts::QLineSeries *series;
|
||||
QtCharts::QValueAxis *xaxis;
|
||||
QtCharts::QValueAxis *yaxis;
|
||||
QChart *chart;
|
||||
QLineSeries *series;
|
||||
QValueAxis *xaxis;
|
||||
QValueAxis *yaxis;
|
||||
};
|
||||
} // namespace QtCharts
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
|
||||
@ -564,14 +564,16 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
// process key event in parent class
|
||||
QPlainTextEdit::keyPressEvent(event);
|
||||
|
||||
// if enabled, try pop up completion automatically after 3 characters
|
||||
// if enabled, try pop up completion automatically after 2 characters
|
||||
if (automatic_completion) {
|
||||
auto cursor = textCursor();
|
||||
auto line = cursor.block().text();
|
||||
if (line.isEmpty()) return;
|
||||
|
||||
// QTextCursor::WordUnderCursor is unusable here since recognizes '/' as word boundary.
|
||||
// Work around it by manually searching for the location of the beginning of the word.
|
||||
int begin = cursor.positionInBlock();
|
||||
int begin = qMin(cursor.positionInBlock(), line.length() - 1);
|
||||
|
||||
while (begin >= 0) {
|
||||
if (line[begin].isSpace()) break;
|
||||
--begin;
|
||||
@ -748,7 +750,7 @@ void CodeEditor::runCompletion()
|
||||
// QTextCursor::WordUnderCursor is unusable here since it recognizes '/' as word boundary.
|
||||
// Work around it by manually searching for the beginning and end position of the word
|
||||
// under the cursor and then using that substring.
|
||||
int begin = cursor.positionInBlock();
|
||||
int begin = qMin(cursor.positionInBlock(), line.length() - 1);
|
||||
line = cursor.block().text();
|
||||
while (begin >= 0) {
|
||||
if (line[begin].isSpace()) break;
|
||||
@ -990,8 +992,26 @@ void CodeEditor::insertCompletedCommand(const QString &completion)
|
||||
{
|
||||
auto *completer = qobject_cast<QCompleter *>(sender());
|
||||
if (completer->widget() != this) return;
|
||||
|
||||
// select the entire word (non-space text) under the cursor
|
||||
// we need to do it in this compicated way, since QTextCursor does not recognize
|
||||
// special characters as part of a word.
|
||||
auto cursor = textCursor();
|
||||
cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
|
||||
auto line = cursor.block().text();
|
||||
int begin = cursor.positionInBlock();
|
||||
do {
|
||||
if (line[begin].isSpace()) break;
|
||||
--begin;
|
||||
} while (begin >= 0);
|
||||
|
||||
int end = begin + 1;
|
||||
while (end < line.length()) {
|
||||
if (line[end].isSpace()) break;
|
||||
++end;
|
||||
}
|
||||
|
||||
cursor.setPosition(cursor.position() - cursor.positionInBlock() + begin + 1);
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, end - begin - 1);
|
||||
cursor.insertText(completion);
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QImage>
|
||||
#include <QImageReader>
|
||||
#include <QKeySequence>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMenuBar>
|
||||
@ -131,7 +132,7 @@ static const QString blank(" ");
|
||||
|
||||
ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidget *parent) :
|
||||
QDialog(parent), menuBar(new QMenuBar), imageLabel(new QLabel), scrollArea(new QScrollArea),
|
||||
lammps(_lammps), group("all"), filename(fileName), useelements(false)
|
||||
lammps(_lammps), group("all"), filename(fileName), useelements(false), usediameter(false)
|
||||
{
|
||||
imageLabel->setBackgroundRole(QPalette::Base);
|
||||
imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||
@ -268,7 +269,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge
|
||||
// properties directly since lookup in reset_view() will have failed
|
||||
dobox->setChecked(showbox);
|
||||
dovdw->setChecked(vdwfactor > 1.0);
|
||||
dovdw->setEnabled(useelements);
|
||||
dovdw->setEnabled(useelements || usediameter);
|
||||
doaxes->setChecked(showaxes);
|
||||
dossao->setChecked(usessao);
|
||||
doanti->setChecked(antialias);
|
||||
@ -435,7 +436,7 @@ void ImageViewer::createImage()
|
||||
dumpcmd += "'" + dumpfile.fileName() + "'";
|
||||
|
||||
settings.beginGroup("snapshot");
|
||||
int hhrot = (hrot > 180) ? 360 - hrot : hrot;
|
||||
int hhrot = (hrot > 180) ? 360 - hrot : hrot;
|
||||
|
||||
// determine elements from masses and set their covalent radii
|
||||
int ntypes = lammps->extract_setting("ntypes");
|
||||
@ -454,9 +455,10 @@ void ImageViewer::createImage()
|
||||
adiams += QString("adiam %1 %2 ").arg(i).arg(vdwfactor * pte_vdw_radius[idx]);
|
||||
}
|
||||
}
|
||||
usediameter = lammps->extract_setting("radius_flag") != 0;
|
||||
|
||||
// adjust pushbutton state and clear adiams string to disable VDW display, if needed
|
||||
if (useelements) {
|
||||
if (useelements || usediameter) {
|
||||
auto *button = findChild<QPushButton *>("vdw");
|
||||
if (button) button->setEnabled(true);
|
||||
} else {
|
||||
@ -469,7 +471,10 @@ void ImageViewer::createImage()
|
||||
dumpcmd += blank + "element";
|
||||
else
|
||||
dumpcmd += blank + settings.value("color", "type").toString();
|
||||
dumpcmd += blank + settings.value("diameter", "type").toString();
|
||||
if (usediameter && (vdwfactor > 1.0))
|
||||
dumpcmd += blank + "diameter";
|
||||
else
|
||||
dumpcmd += blank + settings.value("diameter", "type").toString();
|
||||
dumpcmd += QString(" size %1 %2").arg(xsize).arg(ysize);
|
||||
dumpcmd += QString(" zoom %1").arg(zoom);
|
||||
dumpcmd += " shiny 0.5 ";
|
||||
@ -528,10 +533,10 @@ void ImageViewer::copy() {}
|
||||
|
||||
void ImageViewer::quit()
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
main->quit();
|
||||
if (main) main->quit();
|
||||
}
|
||||
|
||||
void ImageViewer::saveFile(const QString &fileName)
|
||||
@ -554,10 +559,10 @@ void ImageViewer::createActions()
|
||||
fileMenu->addSeparator();
|
||||
QAction *exitAct = fileMenu->addAction("&Close", this, &QWidget::close);
|
||||
exitAct->setIcon(QIcon(":/icons/window-close.png"));
|
||||
exitAct->setShortcut(QKeySequence::fromString("Ctrl+W"));
|
||||
exitAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_W));
|
||||
QAction *quitAct = fileMenu->addAction("&Quit", this, &ImageViewer::quit);
|
||||
quitAct->setIcon(QIcon(":/icons/application-exit.png"));
|
||||
quitAct->setShortcut(QKeySequence::fromString("Ctrl+Q"));
|
||||
quitAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
|
||||
}
|
||||
|
||||
void ImageViewer::updateActions()
|
||||
|
||||
@ -88,7 +88,7 @@ private:
|
||||
int xsize, ysize;
|
||||
int hrot, vrot;
|
||||
double zoom, vdwfactor;
|
||||
bool showbox, showaxes, antialias, usessao, useelements;
|
||||
bool showbox, showaxes, antialias, usessao, useelements, usediameter;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <QLabel>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QMetaType>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QProcess>
|
||||
#include <QProgressBar>
|
||||
@ -69,8 +70,10 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
|
||||
// enforce using the plain ASCII C locale within the GUI.
|
||||
QLocale::setDefault(QLocale("C"));
|
||||
|
||||
// register QList<QString>
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
// register QList<QString> only needed for Qt5
|
||||
qRegisterMetaTypeStreamOperators<QList<QString>>("QList<QString>");
|
||||
#endif
|
||||
|
||||
ui->setupUi(this);
|
||||
this->setCentralWidget(ui->textEdit);
|
||||
@ -81,9 +84,13 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
|
||||
// use $HOME if we get dropped to "/" like on macOS
|
||||
if (current_dir == "/") current_dir = QDir::homePath();
|
||||
|
||||
#define stringify(x) myxstr(x)
|
||||
#define myxstr(x) #x
|
||||
QCoreApplication::setOrganizationName("The LAMMPS Developers");
|
||||
QCoreApplication::setOrganizationDomain("lammps.org");
|
||||
QCoreApplication::setApplicationName("LAMMPS GUI");
|
||||
QCoreApplication::setApplicationName("LAMMPS GUI - QT" stringify(QT_VERSION_MAJOR));
|
||||
#undef stringify
|
||||
#undef myxstr
|
||||
|
||||
// restore and initialize settings
|
||||
QSettings settings;
|
||||
@ -588,7 +595,8 @@ void LammpsGui::open_file(const QString &fileName)
|
||||
if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
|
||||
QMessageBox::warning(this, "Warning",
|
||||
"Cannot open file " + path.absoluteFilePath() + ": " +
|
||||
file.errorString() + ".\nWill create new file on saving editor buffer.");
|
||||
file.errorString() +
|
||||
".\nWill create new file on saving editor buffer.");
|
||||
ui->textEdit->document()->setPlainText(QString());
|
||||
} else {
|
||||
QTextStream in(&file);
|
||||
@ -1039,9 +1047,9 @@ void LammpsGui::do_run(bool use_buffer)
|
||||
logwindow->document()->setDefaultFont(text_font);
|
||||
logwindow->setLineWrapMode(LogWindow::NoWrap);
|
||||
logwindow->setMinimumSize(400, 300);
|
||||
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), logwindow);
|
||||
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_W), logwindow);
|
||||
QObject::connect(shortcut, &QShortcut::activated, logwindow, &LogWindow::close);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Slash), logwindow);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Slash), logwindow);
|
||||
QObject::connect(shortcut, &QShortcut::activated, this, &LammpsGui::stop_run);
|
||||
if (settings.value("viewlog", true).toBool())
|
||||
logwindow->show();
|
||||
@ -1058,9 +1066,9 @@ void LammpsGui::do_run(bool use_buffer)
|
||||
.arg(run_counter));
|
||||
chartwindow->setWindowIcon(QIcon(":/icons/lammps-icon-128x128.png"));
|
||||
chartwindow->setMinimumSize(400, 300);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), chartwindow);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_W), chartwindow);
|
||||
QObject::connect(shortcut, &QShortcut::activated, chartwindow, &ChartWindow::close);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Slash), chartwindow);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Slash), chartwindow);
|
||||
QObject::connect(shortcut, &QShortcut::activated, this, &LammpsGui::stop_run);
|
||||
if (settings.value("viewchart", true).toBool())
|
||||
chartwindow->show();
|
||||
|
||||
@ -16,8 +16,10 @@
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QSpacerItem>
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@ -35,12 +35,14 @@ LogWindow::LogWindow(const QString &_filename, QWidget *parent) :
|
||||
QSettings settings;
|
||||
resize(settings.value("logx", 500).toInt(), settings.value("logy", 320).toInt());
|
||||
|
||||
auto action = new QShortcut(QKeySequence::fromString("Ctrl+S"), this);
|
||||
auto action = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_S), this);
|
||||
connect(action, &QShortcut::activated, this, &LogWindow::save_as);
|
||||
action = new QShortcut(QKeySequence::fromString("Ctrl+Q"), this);
|
||||
action = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q), this);
|
||||
connect(action, &QShortcut::activated, this, &LogWindow::quit);
|
||||
action = new QShortcut(QKeySequence(Qt::Key_Slash, Qt::CTRL), this);
|
||||
action = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Slash), this);
|
||||
connect(action, &QShortcut::activated, this, &LogWindow::stop_run);
|
||||
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
void LogWindow::closeEvent(QCloseEvent *event)
|
||||
@ -55,18 +57,18 @@ void LogWindow::closeEvent(QCloseEvent *event)
|
||||
|
||||
void LogWindow::quit()
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
main->quit();
|
||||
if (main) main->quit();
|
||||
}
|
||||
|
||||
void LogWindow::stop_run()
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
main->stop_run();
|
||||
if (main) main->stop_run();
|
||||
}
|
||||
|
||||
void LogWindow::save_as()
|
||||
@ -99,15 +101,35 @@ void LogWindow::contextMenuEvent(QContextMenuEvent *event)
|
||||
menu->addSeparator();
|
||||
auto action = menu->addAction(QString("Save Log to File ..."));
|
||||
action->setIcon(QIcon(":/icons/document-save-as.png"));
|
||||
action->setShortcut(QKeySequence::fromString("Ctrl+S"));
|
||||
action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
|
||||
connect(action, &QAction::triggered, this, &LogWindow::save_as);
|
||||
action = menu->addAction("&Close Window", this, &QWidget::close);
|
||||
action->setIcon(QIcon(":/icons/window-close.png"));
|
||||
action->setShortcut(QKeySequence::fromString("Ctrl+W"));
|
||||
action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_W));
|
||||
menu->exec(event->globalPos());
|
||||
delete menu;
|
||||
}
|
||||
|
||||
// event filter to handle "Ambiguous shortcut override" issues
|
||||
bool LogWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ShortcutOverride) {
|
||||
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
|
||||
if (!keyEvent) return QWidget::eventFilter(watched, event);
|
||||
if (keyEvent->modifiers().testFlag(Qt::ControlModifier) && keyEvent->key() == '/') {
|
||||
stop_run();
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
if (keyEvent->modifiers().testFlag(Qt::ControlModifier) && keyEvent->key() == 'W') {
|
||||
close();
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
|
||||
@ -30,6 +30,7 @@ private slots:
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
QString filename;
|
||||
|
||||
@ -286,12 +286,12 @@ GeneralTab::GeneralTab(QSettings *_settings, LammpsWrapper *_lammps, QWidget *pa
|
||||
|
||||
void GeneralTab::updatefonts(const QFont &all, const QFont &text)
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
|
||||
QApplication::setFont(all);
|
||||
main->ui->textEdit->document()->setDefaultFont(text);
|
||||
if (main) main->ui->textEdit->document()->setDefaultFont(text);
|
||||
}
|
||||
|
||||
void GeneralTab::newallfont()
|
||||
@ -410,11 +410,19 @@ AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWi
|
||||
#endif
|
||||
auto *choices = new QFrame;
|
||||
auto *choiceLayout = new QVBoxLayout;
|
||||
#if defined(_OPENMP)
|
||||
auto *ntlabel = new QLabel(QString("Number of threads (max %1):").arg(maxthreads));
|
||||
auto *ntchoice = new QLineEdit(settings->value("nthreads", maxthreads).toString());
|
||||
#else
|
||||
auto *ntlabel = new QLabel(QString("Number of threads (OpenMP not available):"));
|
||||
auto *ntchoice = new QLineEdit("1");
|
||||
#endif
|
||||
auto *intval = new QIntValidator(1, maxthreads, this);
|
||||
ntchoice->setValidator(intval);
|
||||
ntchoice->setObjectName("nthreads");
|
||||
#if !defined(_OPENMP)
|
||||
ntchoice->setEnabled(false);
|
||||
#endif
|
||||
|
||||
choiceLayout->addWidget(ntlabel);
|
||||
choiceLayout->addWidget(ntchoice);
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include <QHBoxLayout>
|
||||
#include <QImage>
|
||||
#include <QImageReader>
|
||||
#include <QKeySequence>
|
||||
#include <QLabel>
|
||||
#include <QPalette>
|
||||
#include <QProcess>
|
||||
@ -50,11 +51,11 @@ SlideShow::SlideShow(const QString &fileName, QWidget *parent) :
|
||||
imageName->setAlignment(Qt::AlignCenter);
|
||||
imageName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
auto *shortcut = new QShortcut(QKeySequence::fromString("Ctrl+W"), this);
|
||||
auto *shortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_W), this);
|
||||
QObject::connect(shortcut, &QShortcut::activated, this, &QWidget::close);
|
||||
shortcut = new QShortcut(QKeySequence::fromString("Ctrl+/"), this);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Slash), this);
|
||||
QObject::connect(shortcut, &QShortcut::activated, this, &SlideShow::stop_run);
|
||||
shortcut = new QShortcut(QKeySequence::fromString("Ctrl+Q"), this);
|
||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q), this);
|
||||
QObject::connect(shortcut, &QShortcut::activated, this, &SlideShow::quit);
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
|
||||
@ -198,18 +199,18 @@ void SlideShow::loadImage(int idx)
|
||||
|
||||
void SlideShow::quit()
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
main->quit();
|
||||
if (main) main->quit();
|
||||
}
|
||||
|
||||
void SlideShow::stop_run()
|
||||
{
|
||||
LammpsGui *main;
|
||||
LammpsGui *main = nullptr;
|
||||
for (QWidget *widget : QApplication::topLevelWidgets())
|
||||
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
|
||||
main->stop_run();
|
||||
if (main) main->stop_run();
|
||||
}
|
||||
|
||||
void SlideShow::movie()
|
||||
|
||||
@ -77,6 +77,7 @@ bool StdCapture::EndCapture()
|
||||
|
||||
int bytesRead;
|
||||
bool fd_blocked;
|
||||
int maxwait = 100;
|
||||
|
||||
do {
|
||||
bytesRead = 0;
|
||||
@ -93,9 +94,10 @@ bool StdCapture::EndCapture()
|
||||
buf[bytesRead] = 0;
|
||||
m_captured += buf;
|
||||
} else if (bytesRead < 0) {
|
||||
fd_blocked = ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR));
|
||||
fd_blocked = ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR)) && (maxwait > 0);
|
||||
|
||||
if (fd_blocked) std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
--maxwait;
|
||||
}
|
||||
} while (fd_blocked || (bytesRead == (bufSize - 1)));
|
||||
m_capturing = false;
|
||||
|
||||
Reference in New Issue
Block a user