Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Essential Qt Development Concepts and Best Practices

Tech 3

Core UI and Threading Constraints

Qt enforces strict thread affinity for GUI operations. UI elements must only be accessed from the main (GUI) thread. Attempting to manipulate widgets like QLabel or QPushButton from a worker thread leads to undefined behavior or crashes.

Similarly, QTimer objects are bound to the thread in which they are created and cannot be started or stopped from another thread.

Layout and Widget Behavior

When a widget has a fixed size (via setFixedSize), layout stretch factors (setStretch) do not resize it but still reserve proportional space around it.

Key layout functions:

  • setStretch(index, factor): Controls how much a widget expands relative to others.
  • setSpacing(pixels): Sets spacing between adjacent widgets.
  • setContentsMargins(left, top, right, bottom): Replaces the deprecated setMargin, defining padding inside the layout edges.

QTabWidget combines a QTabBar (the clickable tabs) with a stack of QWidget pages. They serve complementary roles.

Slider, ScrollBar, and ProgressBar Differences

  • QSlider: Selects a value within a range (e.g., volume control).
  • QScrollBar: Navigates content that exceeds viewport bounds.
  • QProgressBar: Visually indicates task completion percentage.

QScrollArea is a container that automatically provides scroll bars when its child widget exceeds the visible area, whereas QScrollBar is a standalone scrollbar component.

String and Data Containers

QStringList is a convenience typedef of QList<QString> with extra string-specific methods like join() or filter(). Use it for string manipulation; use QList<QString> when treating strings as generic list elements.

QFileInfoList is simply an alias for QList<QFileInfo>, commonly used with QDir::entryInfoList() to retrieve file metadata.

Date, Time, and Encoding

Get today’s date formatted as "yyyy-MM-dd":

QString today = QDate::currentDate().toString("yyyy-MM-dd");

Qt uses UTF-8 internally for QString. Conversion to C-style strings requires intermediate steps:

char* cstr = str.toUtf8().data(); // Safe two-step conversion

Avoid toLocal8Bit() unless interfacing with legacy Windows ANSI APIs.

Prefer QStringLiteral("text") for compile-time optimized static strings.

Application Types

  • QCoreApplication: For non-GUI apps (console tools).
  • QApplication: Required for GUI applications, inherits from QGuiApplication.

File and Directory Handling

Use QFile for I/O, QFileInfo for metadata (size, permissions), and QDir for directory navigation. When listing entries, exclude "." and ".." using:

QDir dir(path);
auto entries = dir.entryInfoList(QDir::Files | QDir::Dirs, QDir::NoDotAndDotDot);

For high-frequency logging, keep the file open instead of repeatedly opening/closing to avoid I/O bottlenecks.

Performence and Safety

  • Use at() instead of operator[] for read-only access to Qt containers to avoid unnecessary deep copies due to implicit sharing.
  • Prefer deleteLater() over delete for QObject-derived classes to defer deletion until safe.
  • For batch deletion: qDeleteAll(widgetList);

Styling and Custom Drawing

Custom QWidget subclasses ignore style sheets by default. Enable styling with:

setAttribute(Qt::WA_StyledBackground, true);

To center a widget inside a table cell:

auto progress = new QProgressBar;
auto container = new QWidget;
auto layout = new QHBoxLayout(container);
layout->addWidget(progress);
layout->setContentsMargins(0, 0, 0, 0);
table->setCellWidget(row, col, container);

Use QPainter with QStyle::drawControl() and QStyleOption for advanced custom delegates in views.

Signals and Architecture

For complex signal routing across deeply nested widgets, use a global event dispatcher (singleton) to decouple components:

// AppEvent.h
class AppEvent : public QObject { Q_OBJECT
public:
    static AppEvent* instance() { static AppEvent inst; return &inst; }
signals:
    void dataUpdated(const QString&);
};

// Usage
connect(source, &Source::changed, AppEvent::instance(), &AppEvent::dataUpdated);
connect(AppEvent::instance(), &AppEvent::dataUpdated, target, &Target::refresh);

Miscellaneous Tips

  • Avoid Chinese text inside tr(); use English source strings for proper i18n.
  • Use #if 0 ... #endif for large code blocks to toggle quickly.
  • On Windows, $$PWD in .pro files resolves to the current project directory.
  • When passing QImage across threads via signals, ensure deep copying (Qt handles this automatically if the type is registered).
  • Disable column resizing in tables:
    tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
    
  • Compute readable text color from background:
    auto gray = (0.299 * bg.red() + 0.587 * bg.green() + 0.114 * bg.blue()) / 255.0;
    auto fg = gray > 0.5 ? Qt::black : Qt::white;
    
Tags: qt

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.