{
  "schema_version": 2,
  "id": "develop/clients/hiredis/int-examples/qt-integration",
  "title": "Integrate hiredis with a Qt app",
  "url": "https://redis.io/docs/latest/develop/clients/hiredis/int-examples/qt-integration/",
  "summary": "Use `hiredis` in conjunction with the Qt app framework.",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-09T11:06:49+01:00",
  "page_type": "content",
  "content_hash": "0297224b393f5bcceda05ad574adf6adad17fcefc5cd5f60aeafe25a627b6ca4",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "[Qt](https://www.qt.io/) is a popular cross-platform C++ framework that\nyou can use to build command line and GUI apps. This guide explains how\nto use `hiredis` to connect to a Redis server from a Qt app."
    },
    {
      "id": "install-qt",
      "title": "Install Qt",
      "role": "setup",
      "text": "You should first download and install the\n[Qt development environment](https://www.qt.io/download-dev) for your\ndevelopment platform, if you have not already done so. The example\nbelow briefly explains how to use Qt Creator\nto manage your project, but see the [Qt Creator](https://doc.qt.io/qtcreator/)\ndocs for an extensive set of examples and tutorials."
    },
    {
      "id": "create-a-simple-app",
      "title": "Create a simple app",
      "role": "content",
      "text": "We will use a simple console app to demonstrate how to connect\nto Redis from Qt. Create the app project in Qt Creator using the\n**File > New Project** command. The generated source code is a\nsingle C++ file, called `main.cpp`, that uses a\n[`QCoreApplication`](https://doc.qt.io/qt-6/qcoreapplication.html)\nobject to handle the main event loop. Although it will compile and run,\nit doesn't do anything useful at this stage."
    },
    {
      "id": "add-hiredis-files",
      "title": "Add `hiredis` files",
      "role": "content",
      "text": "Build `hiredis` if you have not already done so (see\n[Build and install](https://redis.io/docs/latest/develop/clients/hiredis#build-and-install)\nfor more information).\n\nYou should also make the `libhiredis` library available to the project. For example,\nif you have used the default option of [`cmake`](https://cmake.org/) as the project\nbuild tool and you have installed the `.dylib` or `.so` file for `hiredis` in `/usr/local/lib`,\nyou should add the following lines to the `CMakeLists.txt` file:\n\n[code example]\n\nYou should also modify the `target_link_libraries` directive to include\n`hiredis`:\n\n[code example]"
    },
    {
      "id": "add-code-to-access-redis",
      "title": "Add code to access Redis",
      "role": "content",
      "text": "You can add a class using the **Add new** context menu\non the project folder in Qt Creator. The sections below give\nexamples of the code you should add to this class to\nconnect to Redis. The code is separated into header and\nimplementation files."
    },
    {
      "id": "header-file",
      "title": "Header file",
      "role": "content",
      "text": "The header file for a class called `RedisExample` is shown below.\nAn explanation follows the code.\n\n[code example]\n\n[`QObject`](https://doc.qt.io/qt-6/qobject.html) is a key Qt class that\nimplements the [Object model](https://doc.qt.io/qt-6/object.html) for\ncommunication between objects. When you create your class in Qt Creator,\nyou can specify that you want it to be a subclass of `QObject` (this will\nadd the appropriate header files and include the `Q_OBJECT` macro in the\nclass declaration).\n\nThe `QObject` communication model uses some instance methods as *signals*\nto report events and others as *slots* to act as callbacks that process the\nevents (see [Signals and slots](https://doc.qt.io/qt-6/signalsandslots.html)\nfor an introduction). The Qt [meta-object compiler](https://doc.qt.io/qt-6/moc.html)\nrecognizes the non-standard C++ access specifiers `signals:` and `slots:`  in the\nclass declaration and adds extra code for them during compilation to enable\nthe communication mechanism.\n\nIn our class, there is a `run()` slot that will implement the code to access Redis.\nThe code eventually emits a `finished()` signal when it is complete to indicate that\nthe app should exit.\n\nOur simple example code just sets and gets a Redis\n[string](https://redis.io/docs/latest/develop/data-types/strings) key. The class contains\nprivate attributes for the key and value (following the Qt `m_xxx` naming convention\nfor class members). These are set by the constructor along with a call to the\n`QObject` constructor. The other attributes represent the connection context for\nRedis (which should generally be\n[asynchronous](https://redis.io/docs/latest/develop/clients/hiredis/connect#asynchronous-connection)\nfor a Qt app) and an adapter object that `hiredis` uses to integrate with Qt."
    },
    {
      "id": "implementation-file",
      "title": "Implementation file",
      "role": "content",
      "text": "The file that implements the methods declared in the header is shown\nbelow. A full explanation follows the code.\n\n[code example]\n\nThe code that accesses Redis is in the `run()` method (recall that this\nimplements a Qt slot that will be called in response to a signal). The\ncode connects to Redis and stores the connection context pointer in the\n`m_ctx` attribute of the class instance. The call to `m_adapter.setContext()`\ninitializes the Qt support for the context. Note that we need an\nasynchronous connection for Qt. See\n[Asynchronous connection](https://redis.io/docs/latest/develop/clients/hiredis/connect#asynchronous-connection)\nfor more information.\n\nThe code then issues two Redis commands to [`SET`](https://redis.io/docs/latest/commands/set)\nthe string key and value that were supplied using the class's constructor. We are\nnot interested in the response returned by this command, but we are interested in the\nresponse from the [`GET`](https://redis.io/docs/latest/commands/get) command that follows it.\nBecause the commands are asynchronous, we need to set a callback to handle\nthe `GET` response when it arrives. In the `redisAsyncCommand()` call, we pass\na pointer to our `getCallback()` function and also pass a pointer to the\n`RedisExample` instance. This is a custom data field that will simply\nbe passed on to the callback when it executes (see \n[Construct asynchronous commands](https://redis.io/docs/latest/develop/clients/hiredis/issue-commands#construct-asynchronous-commands)\nfor more information).\n\nThe code in the `getCallback()` function starts by casting the reply pointer\nparameter to [`redisReply`](https://redis.io/docs/latest/develop/clients/hiredis/handle-replies)\nand the custom data pointer to `RedisExample`. Here, the example just prints\nthe reply string to the console, but you can process it in any way you like.\nYou can add methods to your class and call them within the callback using the\ncustom data pointer passed during the `redisAsyncCommand()` call. Here, we\nsimply use the pointer to call the `finish()` method.\n\nThe `finish()` method calls\n`redisAsyncDisconnect()` to close the connection and then uses the\nQt signalling mechanism to emit the `finished()` signal. You may need to\nprocess several commands with a particular connection context, but you should\nclose it from a callback when you have finished using it."
    },
    {
      "id": "main-program",
      "title": "Main program",
      "role": "content",
      "text": "To access the `RedisExample` class, you should use code like the\nfollowing in the `main()` function defined in `main.cpp`:\n\n[code example]\n\nThis creates the [`QCoreApplication`](https://doc.qt.io/qt-6/qcoreapplication.html)\ninstance that manages the main event loop for a console app. It\nthen creates the instance of `RedisExample` with the key (\"url\") and\nvalue (\"https://redis.io/\") for our Redis string.\n\nThe two lines below set up the `QObject` communication mechanism\nfor the app. The call to\n[`QTimer::singleShot()`](https://doc.qt.io/qt-6/qtimer.html#singleShot-2)\nactivates the `run()`\nslot method on our `RedisExample` instance. The \n[`QObject::connect()`](https://doc.qt.io/qt-6/qobject.html#connect-5)\ncall creates a communication link between the `finished()` signal of\nout `RedisExample` instance and the `quit()` slot of our\n`QCoreApplication` instance. This quits the application event loop and\nexits the app when the `finished()` signal is emitted by the\n`RedisExample` object. This happens when the `finish()` method is called\nat the end of the `GET` command callback."
    },
    {
      "id": "run-the-code",
      "title": "Run the code",
      "role": "content",
      "text": "When you have added the code, you can run it from the **Build** menu of\nQt Creator or from the toolbar at the left hand side of the window.\nAssuming the connection to Redis succeeds, it will print the message\n`Value: https://redis.io/` and quit. You can use the\n[`KEYS`](https://redis.io/docs/latest/commands/keys) command from\n[`redis-cli`](https://redis.io/docs/latest/develop/tools/cli) or\n[Redis Insight](https://redis.io/docs/latest/develop/tools/insight) to check\nthat the \"url\" string key was added to the Redis database."
    },
    {
      "id": "key-information",
      "title": "Key information",
      "role": "content",
      "text": "There are many ways you could use Redis with a Qt app, but our example\ndemonstrates some techniques that are broadly useful:\n\n-   Use the `QObject` communication mechanism to simplify your code.\n-   Use the `hiredis` asynchronous API. Add a `RedisQtAdapter` instance\n    to your code and ensure you call its `setContext()` method to\n    initialize it before issuing Redis commands.\n-   Place all code and data you need to interact with Redis\n    (including the connection context) in a single\n    class or ensure it is available from a class via pointers and\n    Qt signals. Pass a pointer to an instance of your class in the\n    custom data parameter when you issue a Redis command with\n    `redisAsyncCommand()` and use this to process the reply or\n    issue more commands from the callback."
    }
  ],
  "examples": [
    {
      "id": "add-hiredis-files-ex0",
      "language": "plaintext",
      "code": "add_library(hiredis SHARED IMPORTED)\nset_property(TARGET hiredis PROPERTY\n             IMPORTED_LOCATION \"/usr/local/lib/libhiredis.dylib\")",
      "section_id": "add-hiredis-files"
    },
    {
      "id": "add-hiredis-files-ex1",
      "language": "plaintext",
      "code": "target_link_libraries(ConsoleTest Qt${QT_VERSION_MAJOR}::Core hiredis)",
      "section_id": "add-hiredis-files"
    },
    {
      "id": "header-file-ex0",
      "language": "c++",
      "code": "// redisexample.h\n\n#ifndef REDISEXAMPLE_H\n#define REDISEXAMPLE_H\n\n#include <QObject>\n\n#include <hiredis/hiredis.h>\n#include <hiredis/async.h>\n#include <hiredis/adapters/qt.h>\n\n\nclass RedisExample : public QObject\n{\n    Q_OBJECT\n\npublic:\n    // Constructor\n    RedisExample(const char *keyForRedis, const char *valueForRedis, QObject *parent = 0)\n        :QObject(parent), m_key(keyForRedis), m_value(valueForRedis) {}\n\npublic slots:\n    // Slot method to hold the code that connects to Redis and issues\n    // commands.\n    void run();\n\nsignals:\n    // Signal to indicate that our code has finished executing.\n    void finished();\n\npublic:\n    // Method to close the Redis connection and signal that we've\n    // finished.\n    void finish();\n\nprivate:\n    const char *m_key;          // Key for Redis string.\n    const char *m_value;        // Value for Redis string.\n    redisAsyncContext *m_ctx;   // Redis connection context.\n    RedisQtAdapter m_adapter;   // Adapter to let `hiredis` work with Qt.\n};\n\n#endif // REDISEXAMPLE_H",
      "section_id": "header-file"
    },
    {
      "id": "implementation-file-ex0",
      "language": "c++",
      "code": "// redisexample.cpp\n\n#include <iostream>\n\n#include \"redisexample.h\"\n\n\nvoid RedisExample::finish() {\n    // Disconnect gracefully.\n    redisAsyncDisconnect(m_ctx);\n\n    // Emit the `finished()` signal to indicate that the\n    // execution is complete.\n    emit finished();\n}\n\n\n// Callback used by our `GET` command in the `run()` method.\nvoid getCallback(redisAsyncContext *, void * r, void * privdata) {\n\n    // Cast data pointers to their appropriate types.\n    redisReply *reply = static_cast<redisReply *>(r);\n    RedisExample *ex = static_cast<RedisExample *>(privdata);\n\n    if (reply == nullptr || ex == nullptr) {\n        return;\n    }\n\n    std::cout << \"Value: \" << reply->str << std::endl;\n\n    // Close the Redis connection and quit the app.\n    ex->finish();\n}\n\n\nvoid RedisExample::run() {\n    // Open the connection to Redis.\n    m_ctx = redisAsyncConnect(\"localhost\", 6379);\n\n    if (m_ctx->err) {\n        std::cout << \"Error: \" << m_ctx->errstr << std::endl;\n        finish();\n    }\n\n    // Configure the connection to work with Qt.\n    m_adapter.setContext(m_ctx);\n\n    // Issue some simple commands. For the `GET` command, pass a\n    // callback function and a pointer to this object instance\n    // so that we can access the object's members from the callback.\n    redisAsyncCommand(m_ctx, NULL, NULL, \"SET %s %s\", m_key, m_value);\n    redisAsyncCommand(m_ctx, getCallback, this, \"GET %s\", m_key);\n}",
      "section_id": "implementation-file"
    },
    {
      "id": "main-program-ex0",
      "language": "c++",
      "code": "#include <QCoreApplication>\n#include <QTimer>\n\n#include \"redisexample.h\"\n\n\nint main(int argc, char *argv[])\n{\n    QCoreApplication app(argc, argv);\n\n    // Instance of our object.\n    RedisExample r(\"url\", \"https://redis.io/\");\n\n    // Call the `run()` slot on our `RedisExample` instance to\n    // run our Redis commands. \n    QTimer::singleShot(0, &r, SLOT(run()));\n\n    // Set up a communication connection between our `finished()`\n    // signal and the application's `quit()` slot.\n    QObject::connect(&r, SIGNAL(finished()), &app, SLOT(quit()));\n\n    // Start the app's main event loop.\n    return app.exec();\n}",
      "section_id": "main-program"
    }
  ]
}
