QObject

COS2614 - Programming: Contemporary Concepts · Higher-Level Programming

QObject

The QObject class is a fundamental part of the Qt framework. It provides the core features for all Qt objects, such as object naming, signal and slot mechanism, and event handling. Understanding QObject is essential for creating effective applications in Qt, as it underlies most of the framework's functionality.

Key idea: After studying this topic, you should be able to:

  • Explain the role of QObject in the Qt framework.
  • Implement classes that inherit from QObject.
  • Utilise signals and slots for communication between objects.
  • Manage object properties using QVariant.

What is QObject?

QObject is the base class for all Qt objects. It provides essential features such as:

  • Object naming
  • Memory management
  • Signal and slot mechanism
  • Event handling

Every class that derives from QObject can use these features, making it easier to create complex applications. For example, when you create a custom widget, you typically inherit from QWidget, which in turn inherits from QObject.

Creating a QObject Class

When creating a class that inherits from QObject, you must declare the Q_OBJECT macro in the class definition. This macro enables the meta-object features of QObject, such as signals and slots.

class MyObject : public QObject {
Q_OBJECT
public:
MyObject(QObject *parent = nullptr) : QObject(parent) {}
};

In this example, MyObject is a class that inherits from QObject. The constructor takes an optional parent parameter, which is common in Qt to manage object hierarchies.

Signals and Slots

Signals and slots are a powerful mechanism for communication between objects in Qt. A signal is emitted when a particular event occurs, and a slot is a function that is called in response to a signal.

To use signals and slots, you need to declare them in your class. For example:

class MyObject : public QObject {
Q_OBJECT
public:
MyObject(QObject *parent = nullptr) : QObject(parent) {}
signals:
void mySignal();
public slots:
void mySlot();
};

In this code, mySignal is a signal that can be emitted, and mySlot is a slot that can be connected to a signal. To connect a signal to a slot, you can use the connect() function:

QObject::connect(sender, &SenderClass::mySignal, receiver, &ReceiverClass::mySlot);

This line connects the mySignal signal from the sender object to the mySlot slot in the receiver object.

Using QVariant for Properties

QObject also provides a way to manage properties using the QVariant class. QVariant can store different types of values, making it useful for dynamic properties.

To declare a property in your class, use the Q_PROPERTY macro:

class MyObject : public QObject {
Q_OBJECT
Q_PROPERTY(int myProperty READ myProperty WRITE setMyProperty)
public:
MyObject(QObject *parent = nullptr) : QObject(parent), m_myProperty(0) {}
int myProperty() const { return m_myProperty; }
void setMyProperty(int value) { m_myProperty = value; emit myPropertyChanged(); }
signals:
void myPropertyChanged();
private:
int m_myProperty;
};

Here, myProperty is a property of type int. The READ and WRITE keywords specify the getter and setter functions. The property can also emit a signal when it changes.

Watch out: Remember to include the Q_OBJECT macro in any class that inherits from QObject. Without it, signals and slots will not work.

Event Handling

QObject provides a method called event() that allows you to handle events. To create a custom event handler, you must override the event() method in your class:

bool MyObject::event(QEvent *event) {
if (event->type() == QEvent::User) {
// Handle the custom event
return true;
}
return QObject::event(event);
}

In this example, if the event type is a user-defined event, it is handled accordingly. Otherwise, the base class event handler is called.

Summary

  • QObject is the base class for all Qt objects.
  • Signals and slots allow for communication between objects.
  • Properties can be managed using QVariant.
  • Custom events can be handled by overriding the event() method.

Check your understanding

  1. What is the purpose of the Q_OBJECT macro?
  2. How do you connect a signal to a slot in Qt?
  3. What is QVariant, and why is it useful?
  4. How can you handle custom events in a QObject-derived class?