Joshua's Docs - QT / C++ and QML Cheatsheet (with a bit of JS too)

Folder Structure / Files

Unique QT File Types

File Type What Notes
*.qrc Qt Resource Collection file. XML based file used to group resources together and register them with the QT's resource collection process (rcc).

If you are using *.qml files, you probably want to register them in qml.qrc.
*.pro QT Project File A QT project file serves double-duty as both the file that the QT Editor parses to open your project to edit it, and as the main user-editable make instructions. When using QMake with QT, the QMake system actually generated Makefiles from the *.pro file.

Uses a special syntax, variables, and macros. See QMake/Pro subheading for more details.
*.pri Qt Project Include File Very similar to a *.pro; you can use QMake syntax to define variables, add headers and source files, etc. The main difference is that *.pri files should be called / included by a single *.pro file; they should not be run directly against QMake.

Think of them as similar to .qrc files - a good way to organize logical groupings of files and feed into another input. See this S/O and this doc page for details.
*.qml QML File The QML language is a special declarative UI language developed and maintained by QT, and is one of the (IMHO) biggest advantages to using QT. QML files contain only QML code (which also can contain a subset of pseudo-JavaScript), and do not contain C++ code.

Reminders to self about common pitfalls

  • Binding checkboxes to member property and/or MOC property
    • The problem here is multifold:
        1. that you are likely to create a binding that you don't actually want. If the state of the checkbox is bound to the property value, then even if a you have a cancel button, that won't undo the state change prompted by the checkbox
        1. Binding checkboxes directly to members is notoriously tricky with QT. The binding tends to break once the user actually interacts with the checkbox, which defeats the purpose. See S/O 1
    • Solutions:
      • A) Don't bind to members - bind to methods (getters), and use temp backing field for storage! For the Q_PROPERTY macro, unfortunately this means writing some simple getter boilerplate
      • B) Leave bound to member, but use Qt.binding to restore the binding after each checkbox click (see linked S/O solution)
      • C) Use local JS "backing fields" as a temporary value store, that works inbetween the actual members and the local UI state
    • Note that both B & C will still potentially invoke issue #1, unless you do something to make sure that the local state copy is completely detached from the original
      • For example, if you are cloning an entire MOC generated object, you might want to do something like:
        Item {
        	id: root
        	property var stateCopy: JSON.parse(JSON.stringify(stateCopy))
        }
      • There are other benefits to writing getter methods to use Method A aside from this issue; for example, exposing private members to other classes
  • Trouble building with OpenSSL
    • Make sure you trying to use a compatible version of OpenSSL.
      • For example, if you want to use v1.1.1 of OpenSSL, you would need Qt v5.12.4 or up.
      • Check QT docs and release notes for compatibility
    • Make sure you understand dynamic vs static linking
      • Dynamic linking, in this scenario, means that you need to ship OpenSSL DLLs to the end users (or prompt them to install), and OpenSSL has no impact on your actual compile process
      • Static linking can be complicated - you need matching versions to go with compiler, + static files, + it requires that you have the variations for different compile targets and actually recompile
    • If you are trying to static link, do you have the DLLs and the static lib files? You need both to static link.

QML Notes and Tips

  • Misc Tips
    • Invalid property assignment: "___" is a read-only property
      • Make sure you are not accidentally using JSON style syntax with a colon. E.g., if filling in the border properties on Rectangle, it is border {}, NOT border: {}
    • Having an element fill its parent
      • You can use anchors.fill: parent as a shortcut for auto-filling to parent container

QMake / .pro files

Adding libraries

The default cross-platform syntax is LIBS += -L{lib_dir_path} -l{lib_name}

Notes:

  • You can specify more than one library residing in a single path:
    • LIBS += -L"C:\Program Files\OpenSSL-Win64\lib" -llibssl -llibcrypto
  • "Why am I seeing LNK1104: cannot open file '__.lib', but I'm only using DLLs?"
    • If you are trying to use a library in a static manner, likely the compiler needs a static library file (the .lib file), which the error is telling you. And/or you need to include header files when adding the library.

Library file types

For understanding .dll vs .a vs .lib, see the Library File Types section in my general programming notes


Creating releases / building

I'm not going to go into much detail, since this is a bit beyond what I have experience with, but here are some general notes I have:

Windows

The windeployqt tool will get you most of the way there for packing up a dynamically-linked release with the required files. This page covers that tool, and building on QT for Windows in general.

To figure out which DLLs windeployqt thinks you need but you actually can get rid of, a method that I have seen recommended a lot, but seems dubious to me personally, is to try and delete DLLs from a temp release folder as the program is running. Most of the time, Windows will block them from being deleted if they are being used by the program because they are "locked" by the process.

Some more (cough) professional tools are listed here.

Relevant links

Markdown Source Last Updated:
Mon Mar 29 2021 08:11:46 GMT+0000 (Coordinated Universal Time)
Markdown Source Created:
Wed Oct 16 2019 05:00:12 GMT+0000 (Coordinated Universal Time)
© 2024 Joshua Tzucker, Built with Gatsby
Feedback