Lila25mila
Lila25milaMarch 4, 2019, 4:08 a.m.

Undocumented QMake

Introduction

Qmake is a very powerful "meta-make" system that can be used to generate makefiles for different compilers and platforms from the same qmake project (.pro) file. Documentation for qmake has improved a lot since Qt3, but some information is still missing. In this article, we will explain everything with examples.


Please note that the information was written for Qt4, but some of them may work in Qt3. By the way, should work in Qt5 or consider deleting it.

Undocumented variables

The simplest kind of control you can have over a generated makefile is to use the built-in variables provided by qmake. Of course, the problem is that many of these variables are not listed in the qmake documentation. But you have a handy list of them all right here (along with a rich source of tricks and hacks written by Trolltech (currently Qt Company - ed.), carefully mined for you). In your qmake installation directory, there is a subdirectory named "mkspecs". It contains definitions for all platform/compiler combinations that qmake supports (note that not all of them are "formally" supported!) At various points there are directories named "features", there you will find qmake code for many things you can enable with the CONFIG variable.

So if you're trying to figure out something like, "How do I change the name of the compiler that is used in the makefile?" or "How can I change the way the copy file is invoked for 'make install'?" and the like, in the mkspecs directory you should look for the name of the variable you want to change.

Here are a few particularly useful ones (as of v4.3.4) found while investigating the qmake source:

  • DATE - current date and time. (V4.3.4)
  • FILE is the current filename that qmake parses. (V4.3.4)
  • LINE is the current line number as parsed by qmake. (V4.3.4)
  • QMAKE_CACHE is the path to any .qmake.cache file in use. (V4.3.4)
  • DIR_SEPARATOR or QMAKE_DIR_SEP is a forward or backslash character, depending on the host platform.
  • IN_PWD - base directory of the source tree. (V4.3.4)
  • QMAKE_NOFORCE - omit the use of the "FORCE" target.
  • QMAKE_utility is the command for the utility that will be assigned to the macro named utility in the generated Makefiles. Utility macro names are used appropriately for various standard purposes. The value of these variables can be changed to specify various utility commands, and the variables - in the form $$variable_name or $(macro_name) - can be used when defining commands for QMAKE_EXTRA_TARGETS. Utility names:
    QMAKE_CHK_DIR_EXISTS
    • QMAKE_COPY
    • QMAKE_COPY_DIR
    • QMAKE_COPY_FILE
  • QMAKE_DEL_DIR
    • QMAKE_DEL_FILE
    • QMAKE_INSTALL_DIR
    • QMAKE_INSTALL_FILE
    • QMAKE_INSTALL_PROGRAM
  • QMAKE_LINK (used to link executable files)
    • QMAKE_LINK_SHLIB
    • QMAKE_MKDIR
    • QMAKE_MOVE
    • QMAKE_QMAKE
    • QMAKE_STRIP
  • QMAKE_SYMBOLIC_LINK (this is assigned to the SYMLINK macro)
  • QMAKE_ARGS - parameters used to call qmake.
  • QMAKE_PROJECT_DEPTH - when using a large number of .pro (and subfolders) in the main .pro it can be convenient to set a value greater than 4 for this variable, this represents the number of subfolders that qmake refers to in relative paths (the depth is set in makefile.cpp = 4). This is especially useful when using Windows (nmake/jom) with spaces in the project's root path.
Custom Tools

The documentation for qmake in Qt4 briefly mentions the possibility of custom "compilers", but unfortunately not much to describe.

There are several special pseudo-variables that you can use inside custom compilers. I say "pseudo-variables" for two reasons: first, they use only one dollar sign; and second, they are evaluated later than anything you would like to use. For this reason, functions like $$replace(...) and operators like ~= won't do what they should - they will act as if you were passing an empty variable to them.

I hope Trolltech (Qt Company) has already given you what you need!

  • QMAKE_FILE_IN is the input name of the file(s), with a path, if provided, that the compiler handles,
  • QMAKE_FILE_OUT - the contents of the "compiler.output" variable for the current value of ${QMAKE_FILE_IN}, i.e. the current output file,
  • QMAKE_FILE_IN_BASE (or QMAKE_FILE_BASE) - current input file name without extension,
  • QMAKE_FILE_IN_PATH (or QMAKE_FILE_PATH) is just the path to the current input file,
  • QMAKE_FILE_OUT_BASE - current output file name without extension,
  • QMAKE_FILE_OUT_PATH - just the path to the current output file,
  • QMAKE_FILE_EXT is the file extension of the input file, including the dot.

The simplest definition of a custom tool usually looks something like this:

idl_c.output = ${QMAKE_FILE_IN}.c
idl_c.input = IDL
idl_c.commands = $${QMAKE_IDL} ${QMAKE_FILE_IN} $${IDLFLAGS} \
                 /h ${QMAKE_FILE_IN}.h /iid ${QMAKE_FILE_IN}.c
idl_c.variable_out = SOURCES
idl_c.name = MIDL

QMAKE_EXTRA_COMPILERS += idl_c

This example runs the Microsoft MIDL compiler on an .ODL file and generates a .c and .h pair with COM host information.

To define a custom tool, you must first choose a name for the compound variable (similar to a structure) to be defined. In the example above, I chose "idl.c".

There are several properties that can be included in a custom tool definition:

  • .commands - Specifies the command to be run on each of the source files. Note that you will need to use a double $ for any normal qmake variables you wish to expand (this does not include QMAKE_FILE_IN and friends),
  • .clean_commands - specifies the commands to be executed to clean up the extra generated output files,
  • .clean - installs files that should be removed with make clean,
  • .depend_command - specifies the command to be executed to generate dependency information,
  • .dependency_type - use one of the standard dependency bypass algorithms built into qmake. Since version 4.3.3, TYPE_C and TYPE_UI are valid.
  • .depends - Installs files that are dependencies for this step. The output of .depend_command, if used, should be listed here. This can also be used to check if the compiler executable itself has changed,
  • .input - sets a qmake variable that contains a list of files this compiler should run on,
  • .name seems to be just an internal name used in qmake; just make sure you use different values for each custom compiler,
  • .output - sets the name of the output file that the step will generate. The variable ${QMAKE_FILE_IN} can be used to base this on the name of the input file. The default is GENERATED_SOURCES,
  • .output_function - Names the function defined with defineReplace that will be used to determine the name of the output file. The variable ${QMAKE_FILE_IN} will be passed to this function and its return value will be used as the name of the output file. Make sure the function exists and actually returns something, otherwise you will get misleading error messages.
  • .variable_out - generated target files output during the build step will be added to this variable. In this case, the step generates a .c file, so the files must be added to SOURCES.
  • .variables - It's not clear exactly what this function does.
  • .verify_function - wired to the function_verify flag in .CONFIG - it's not clear exactly what this function does.

There is also a .CONFIG property, which itself has several special flags that you can set using syntax identical to the main CONFIG variable:

  • combine (combine) - call the compiler with a list of all files in the source variable, and not once for each file,
  • xplicit_dependencies - source comment: "compiler.CONFIG + =xplicit_dependencies means that ONLY compiler.depends can call Makefile dependencies",
  • function_verify - see also .verify_function above,
  • ignore_no_exist - Ignore (do not process) files in the input list that do not exist. If this function is not set, then a warning is issued that the input file is still being processed,
  • moc_verify - most likely ensures that the file must be passed through the moc preprocessor before adding it as a moc target.
  • no_dependencies - do not generate dependencies from files in the source variable,
  • no_link - files that are created should not be added to OBJECTS - i.e. they are not compiled code that needs to be linked,
  • target_predeps - most likely guarantees that the custom compiler will be run first in the project,
  • verify (check) - it is not revealed what this function does. The custom compiler is never called if it is enabled.

Once you have defined a compound variable for a tool, you must then add that compound variable to QMAKE_EXTRA_COMPILERS. This tells qmake to look at the files you specify and run this tool on them.

Examples

Here is another, and unusual, example:

CFLAGS_FILE = .   # Need to give some bogus input
compile_inp.output = compile.inp
compile_inp.input = CFLAGS_FILE
compile_inp.commands = echo >\$(OBJECTS_DIR)compile.inp \$(CXXFLAGS)
compile_inp.name = compile.inp
compile_inp.variable_out = JUNK
compile_inp.CONFIG = no_link
QMAKE_EXTRA_COMPILERS += compile_inp

This tool simply outputs the contents of the CXXFLAGS variable to a file named "compile.inp". Because this tool is designed to create a file with a fixed name, the variable passed to .input contains only "." (current directory), which will always exist (but is not used anywhere in the rule). This rule uses the \$(foo) construct, which outputs GNU Make or NMAKE format variable expansion, basically delaying variable expansion until make or NMAKE is called in the generated makefile.

Way to compile different files with different CXXFLAGS (based on qt/src/gui/painting/painting.pri):

SOURCES_NOOPTIMIZE = somefile.cpp
nooptimize.name = nooptimize
nooptimize.input = SOURCES_NOOPTIMIZE
nooptimize.dependency_type = TYPE_C
nooptimize.variable_out = OBJECTS
nooptimize.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${first(QMAKE_EXT_OBJ)}
nooptimize.commands = $${QMAKE_CXX} $(CXXFLAGS) -O0 $(INCPATH) -c ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} # Note the -O0
QMAKE_EXTRA_COMPILERS += nooptimize

Of course, you can specify various custom flags instead of -O0, which is used to disable optimizations.

And finally, an example of how to call a batch file named "PreBuildEvent.bat" every time you compile your code (tested in VisualStudio based on qt-creator-enterprise-src-3.1.0\share\qtcreator\static. pro):

PRE_BUILD_FILE = ../Applications/PreBuildEvents.bat
# должен использовать переменную в качестве входных данных
PHONY_DEPS = .
PreBuildEvent.input = PHONY_DEPS
# использовать несуществующий файл для выполнения каждый раз
PreBuildEvent.output = phony.txt
# tсистемный вызов командного файла
PreBuildEvent.commands = call $$PRE_BUILD_FILE
# какое-то имя, которое отображается во время исполнения
PreBuildEvent.name = running Pre-Build steps...
# «no_link» сообщает qmake, что нам не нужно добавлять выходные данные в объектные файлы для компоновки, а «no_clean» означает, что для них нет чистого шага.
# «target_predeps» сообщает qmake, что выходные данные этого должны существовать, прежде чем мы сможем выполнить остальную часть нашей компиляции.
PreBuildEvent.CONFIG += no_link no_clean target_predeps
# Добавьте компилятор в список «дополнительных компиляторов».
QMAKE_EXTRA_COMPILERS += PreBuildEvent
Configuration features

There are several "switches" that can be added to the CONFIG variable that affect different qmake behavior (note that this does not include CONFIG functions specific to custom tools or installers):

  • app_bundle - Turns the target into a bundle rather than a standalone executable (Mac only).
  • compile_libtool - Uses "libtool" for compiling, linking, etc. instead of a regular compiler (*nix only).
  • echo_depend_creation - print messages to the screen during dependency creation (*nix only).
  • generate_pbxbuild_makefile - Generates a makefile wrapper for a PowerBuilder project (Mac only).
  • GNUmake - Allows the GNU make tool to determine dependencies (*nix only).
  • lib_bundle - Turns the target into a bundle instead of a standalone library (Mac only).
  • no_autoqmake - Prevents the output makefile from calling qmake if the .pro file has changed.
  • no_empty_targets - ensures that projects based on SUBDIR do not have targets that do nothing (they are filled with "cd." instead).
  • no_fix_and_continue - Disables GCC's "fix and continue" feature (Mac only).
  • no_include_pwd - skips the current directory from the final INCLUDEPATH.
  • no_pb_munge_key - Prevents qmake from caching the MD5 project key (Mac only).
  • no_pbx_xcode - disables XCode support (Mac only).
  • no_smart_library_merge, no_lflags_merge - Prevents removal of duplicate entries in linker flags (*nix only).
  • no_zero_link - Disables GCC's "zero link" feature (Mac only).
  • object_parallel_to_source - recreates the original folder tree for object files (replaces object_with_source).
  • object_with_source - outputs each object file to the same directory as its source file (replaced by object_parallel_to_source in recent versions).
  • rpath_libdirs - Adds QMAKE_LFLAGS_RPATH to link flags (*nix only).
  • ordered - ensures that the projects are built in the specified order.
  • static_and_shared - generates makefiles for static and shared builds. Note that shared_and_static is ignored. Creates a main makefile named $$MAKEFILE (default Makefile) and subsidiary makefiles named $$MAKEFILE.StaticRelease and $$MAKEFILE.SharedRelease if CONFIG contains release (default for unix platforms), or $$MAKEFILE .StaticDebug and $$MAKEFILE.SharedDebug if CONFIG contains debug (default for win32), or both if CONFIG contains debug_and_release (five makefiles in total). The primary makefile will contain a set of {static, shared}{debug, release}[-xxx] targets corresponding to secondary makefiles, which can be used to invoke the corresponding makefile rules. However, the primary default targets (as well as installation and removal) will have only one precondition (only one library file is created by default) depending on the active CONFIG: static-release, static-debug, shared-release, or shared-debug; add static or shared to CONFIG, in addition to static_and_shared, and release or debug, in addition to debug_and_release, to have qmake choose the appropriate target for the first target prerequisite.

There are also a few values that qmake will dynamically set in CONFIG when it writes a makefile (and not when writing XCode project files), other than the main Makefile - i.e. additional auxiliary makefiles when debug_and_release and/or static_and_shared are set :

  • build_pass - A helper makefile is written (build_pass is not set when the main Makefile is written).
  • Debug and DebugBuild - when debug_and_release is set and the makefile extension contains "Debug".
  • Release and ReleaseBuild - when debug_and_release is set and the makefile file name extension contains "Release".
  • Static and StaticBuild - when static_and_shared is set and the makefile filename extension contains "Static".
  • Shared and SharedBuild - when static_and_shared is set and the makefile extension contains "Shared".

When debug_and_release and static_and_shared are used, all four combinations of Debug / Release and Static / Shared will be added in addition to build_pass.

By checking these values in the build_pass area, you can customize the contents of the makefile accordingly. For example, if your source code contains debug output sections that are conditional on the definition of the DEBUG_SECTION preprocessor macro, the following qmake syntax allows you to determine the macro's value at compile time:

build_pass: DebugBuild {
    # Provide compile-time DEBUG_SECTION.
    DEFINES += DEBUG_SECTION=$(DEBUG_SECTION)
    # Provide console output on MS/Windows.
    win32: CONFIG += console
    }

After running qmake with a .pro file containing the above, a developer can create a debug version of the code as follows:

make DEBUG_SECTION=ENABLED_SECTION debug

Here ENABLED_SECTION is the symbol defined in the source code to output the debug section to be enabled. Shared-debug and/or static-debug targets must be specified if static_and_shared was set in the CONFIG list.

Also, there are several values with undefined value:

  • explicitlib - value not set,
  • no_delete_multiple_files - related to custom targets and "make clean",
  • no_fixpath - Changes how qmake changes file paths to be relative (though it's not clear exactly how),
  • subdir_first_pro, cd_change_global - are related to projects using the SUBDIRS template.

Another interesting value for those who are fed up with long compilation logs:

*silent - the generated makefile uses the "echo" command to output lines such as "compiling x.cpp", "moc xh", "linking x.exe".

Do not use a temporary file containing command line flags, for example, for calls. compiler or linker (@C:\TEMP\nm1234.tmp) but write everything directly to the command line (nmake specific). Useful for reproducible build logs:

  • no_batch -? (Для Win32 NMAKE)

Another interesting feature of qmake, at least since Qt4, is that it has an (undocumented) "config" switch that changes the value of the CONFIG variable at runtime without changing the contents of the file being processed. This is especially useful for replacing build targets. Indeed, qmake cannot generate build targets other than the classic "release", "debug", "clean", and "install". Because the CONFIG variable is checked when scopes are resolved, it allows you to create a complex, goal-based project structure that remains human-readable.

#sample project

TARGET = sample
TEMPLATE = app

SOURCES += main.cpp someclass.cpp
HEADERS += someclass.h

target_one {
    DEFINES += _BUILD_ONE_
    SOURCES += someclass_one.cpp
    HEADERS += someclass_one.h
}

target_two {
    DEFINES += _BUILD_TWO_
    SOURCES += someclass_two.cpp
    HEADERS += someclass_two.h
}

The above project will have 4 possible outputs:

  • simple application with only "someclass" implemented
  • same application but with someclass_one added, makefile generation is done with the following command:
qmake -config target_one
  • same application but with someclass_two added, makefile generation is done with the following command:
qmake -config target_two
  • same application but with optional classes added, makefile generation is done with the following command:
qmake -config "target_one target_two"

This trick will be used by Edyuk to allow the .pro format to become as powerful as known standards like .cbp used by Code::Blocks and *.vcproj used by MSVC.

Custom configuration installation

The following undocumented switches can be added to the .CONFIG property of a custom install target (that is, myInstallTarget.CONFIG). The target is the custom installation target if it has been added to the INSTALLS list. It should be noted that "target" is also considered a custom installation target if its .files property has been explicitly defined in the project file.

  • no_check_exist - Creates an install target even if the files to be installed do not exist at the time qmake is run.

Correction: There are two forms qmake can use to install files: INSTALL_FILE and INSTALL_DIR. When an existing directory is being installed and no_check_exist is not applied, the INSTALL_DIR form is used. However, if the directory does not exist when qmake is run (for example, a subdirectory of documentation files that will be created during make) and no_check_exist is used, the INSTALL_FILE form is used, which on Unix systems will fail during make. To prevent this, no_check_exist must not be used, and an empty directory with the given name must be created when qmake is run. To do this, use qmake's "system" function with the appropriate command (it would be "mkdir -p" on Unix systems; just mkdir on Windows) and a directory path (the path must be delimited by the host system).

SUBDIRS projects

SUBDIRS is a powerful method for breaking projects into smaller chunks. Although in fact it is much more powerful than indicated in the documentation.

There are three possible values for the SUBDIRS variable. They can be directories, as stated in the manual, in which case qmake will look for a .pro file with the same name as the directory. It can also be a .pro file, with or without a path, in which case it will go directly to that file. Or, most likely, it could be a variable. In this case, you can customize the behavior with compound variables using the following keywords:

  • subdir - path to the .pro file. The program will behave as if you just specified a directory.
  • file - the .pro file itself. The program will behave as if you had specified the full path and file name.
  • depends - list of other SUBDIRS entries that this entry depends on.
  • makefile - this seems to set the name of the makefile that will be generated and invoked for this purpose.
  • target - this sets the target in the makefile to be called. (Probably most useful in combination with the "makefile" option.)

For example:

TEMPLATE = subdirs
SUBDIRS = sub_lib sub_tests sub_app

sub_lib.subdir = lib
sub_tests.file = tests/proj.pro
sub_tests.depends = sub_lib
sub_app.subdir = app
sub_app.depends = sub_lib

This allows you to use make -j 4 on your fancy quad-core system with a project that has multiple components that depend on each other. To simplify the process a bit, you can define the following test function:

# addSubdirs(subdirs,deps): Adds directories to the project that depend on
# other directories
defineTest(addSubdirs) {
    for(subdirs, 1) {
        entries = $$files($$subdirs)
        for(entry, entries) {
            name = $$replace(entry, [/\\\\], _)
            SUBDIRS += $$name
            eval ($${name}.subdir = $$entry)
            for(dep, 2):eval ($${name}.depends += $$replace(dep, [/\\\\], _))
            export ($${name}.subdir)
            export ($${name}.depends)
        }
    }
    export (SUBDIRS)
}

You can use it like:

addSubdirs (contrib/*)

addSubdirs (src/lib/kernel, contrib/module1 contrib/module2)
addSubdirs (src/lib/gui, src/lib/kernel contrib/module3 contrib/module4)

addSubdirs (src/tests/kernel, src/lib/kernel)
addSubdirs (src/tests/gui, src/lib/gui)

addSubdirs (src/main, src/lib/gui src/lib/kernel)

addSubdirs (src/modules/*, src/lib/kernel)

project that has:

  • several modules that must be compiled first;
  • kernel library for non-GUI stuff that depends on some contrib modules;
  • a GUI library that depends on the kernel library and some other contrib modules;
  • test benches for kernel and gui libs;
  • the main program that uses the GUI and kernel libraries;
  • several modules that depend only on the core lib;
  • is compiled in parallel where possible.
Undocumented modes

In addition to the well-known "-project" and "-makefile" modes, qmake supports several other switches that can put it into different modes.

  • -prl turns it into "prl generation mode". It's not clear what this means, but it's certainly related to the .prl files that are present in the $QTDIR/libs directory;
  • -set and -query turns it into "properties mode". Then qmake can give you the values of some specific Qt variables that are hard-coded into it at build time. In addition, user-selected properties can be determined and queried. These values can be obtained by a Qt application via QLibraryInfo, but the qmake switch lets shell scripts know about them.

Built-in property values:

  • QMAKE_MKSPECS
  • QMAKE_VERSION
  • QT_INSTALL_BINS
  • QT_INSTALL_CONFIGURATION
  • QT_INSTALL_DATA
  • QT_INSTALL_DEMOS
  • QT_INSTALL_DOCS
  • QT_INSTALL_EXAMPLES
  • QT_INSTALL_HEADERS
  • QT_INSTALL_LIBS
  • QT_INSTALL_PLUGINS
  • QT_INSTALL_PREFIX
  • QT_INSTALL_QML
  • QT_INSTALL_TRANSLATIONS
  • QT_VERSION

For example, if Qt 4.1.3 is installed in /usr/local/Trolltech/Qt-4.1.3 (default):

$ qmake -query QT_VERSION
4.1.3

$ qmake -query QT_INSTALL_PREFIX
/usr/local/Trolltech/Qt-4.1.3

User-defined properties are global to the system - they do not apply to individual projects. Under Win32, they are stored in the registry at HKEY_CURRENT_USER\Software\Trolltech\QMake\2.00a.

You can also get the values of these variables using $$ varname .

Undocumented functions

There are some very handy features that are not in the Qt4 documentation. Some of them weren't added until Qt 4.2, so be careful.

Program flow functions

As far as qmake is concerned, these are test functions that belong to their own section:

  • break() - acts like the C break statement.
  • debug (level, msg) - prints a message to the qmake debug log (enabled with the -d option). The "level" option specifies the number of -d options that must be specified to display this message.
  • clear (var) - Initializes a variable to be cleared.
  • export (var) - when writing a custom function, the declared variables are local to the function. To make a variable available to the calling context, use export(var).
    *next() - Acts like a C continue statement.
  • unset (var) - completely removes the variable (it will act as if it was never set).
Replacing a function

These functions return a value:

  • files (glob) - Returns a list of files that match the specified glob pattern.
    Actually this function is documented as a test function.
Undocumented subtleties

Qmake is a really powerful tool, if you're still unsure about this, take a look: scopes can be nested, but can also be combined using logical operators. The following lines are equivalent:

win32|unix {
    VAR += value
}

win32 {
    VAR += value
}

unix {
    VAR += value
}

The wildcard can be used just about anywhere: scopes, values, and so on.

win32-msvc* {
    # same as win32-msvc|win32-mscv.net
}

TEXTS += *.txt

Determining if a static build of Qt is being used:

qtConfig(static) {
 # this is a static build
}
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

Дмитрий
  • March 16, 2019, 9:55 a.m.

Спасибо за статью.
Давно итересует следующий вопрос:
с помощью переменных
QMAKE_TARGET_COMPANY
QMAKE_TARGET_PRODUCT
QMAKE_TARGET_DESCRIPTION
можно задать свойства компилируемой программы, однако русский язык они не поддерживают.
Можно ли это исправить?

Comments

Only authorized users can post comments.
Please, Log in or Sign up
AD

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:20points,
  • Rating points-10
Last comments
ИМ
Игорь МаксимовNov. 22, 2024, 10:51 p.m.
Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiNov. 1, 2024, 12:37 a.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 6:19 p.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 5:51 p.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 9:02 p.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 25, 2024, 1:11 a.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 5:04 p.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 1:49 p.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 7:10 p.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks