Below is a complete example of implementing communication between Qt C++ and Python using shared memory. This example consists of two parts: a Qt C++ application as the writer and a Python script as the reader.
Qt C++ Writer (SharedMemoryWriter)
// main.cpp#include <QCoreApplication>#include <QSharedMemory>#include <QBuffer>#include <QDataStream>#include <QDebug>#include <QThread>
int main(int argc, char *argv[]){ QCoreApplication a(argc, argv);
// Create shared memory object QSharedMemory sharedMemory("QtPythonSharedMemory");
// If shared memory already exists, detach it first if (sharedMemory.isAttached()) { if (!sharedMemory.detach()) { qDebug() << "Unable to detach from shared memory"; return 1; } }
// Prepare data to share QBuffer buffer; buffer.open(QBuffer::ReadWrite); QDataStream out(&buffer);
// Write some example data out << QString("Hello from Qt C++!"); out << QDateTime::currentDateTime(); out << 42;
int size = buffer.size();
// Create shared memory segment if (!sharedMemory.create(size)) { qDebug() << "Unable to create shared memory segment:" << sharedMemory.errorString(); return 1; }
// Lock shared memory and write data sharedMemory.lock(); char *to = (char*)sharedMemory.data(); const char *from = buffer.data().data(); memcpy(to, from, qMin(sharedMemory.size(), size)); sharedMemory.unlock();
qDebug() << "Data written to shared memory, size:" << size << "bytes"; qDebug() << "Shared memory key:" << sharedMemory.nativeKey();
// Keep the program running for a while to allow Python to read QThread::sleep(10);
// Cleanup if (sharedMemory.isAttached()) { sharedMemory.detach(); }
return 0;}
CMakeLists.txt (for Qt C++ project):
cmake_minimum_required(VERSION 3.16)project(SharedMemoryWriter)
set(CMAKE_CXX_STANDARD 17)set(CMAKE_AUTOMOC ON)set(CMAKE_AUTORCC ON)set(CMAKE_AUTOUIC ON)
find_package(Qt6 REQUIRED COMPONENTS Core)
add_executable(SharedMemoryWriter main.cpp)
target_link_libraries(SharedMemoryWriter Qt6::Core)
Python Reader (SharedMemoryReader.py)
import sysimport structfrom datetime import datetimefrom PySide6.QtCore import QSharedMemory, QDataStream, QByteArray, QIODevice# You can also use PyQt6 instead of PySide6
def read_shared_memory(): # Create shared memory object shared_memory = QSharedMemory("QtPythonSharedMemory")
# Try to attach to the shared memory segment if not shared_memory.attach(QSharedMemory.ReadOnly): print("Unable to attach to shared memory segment") return False
# Lock shared memory for reading if not shared_memory.lock(): print("Unable to lock shared memory") return False
try: # Create data stream to read data from shared memory data = QByteArray() data.resize(shared_memory.size()) data = bytearray(shared_memory.data())[:shared_memory.size()]
buffer = QByteArray(data) stream = QDataStream(buffer, QIODevice.ReadOnly)
# Read data in the order it was written message = stream.readQString() timestamp = stream.readQVariant() number = stream.readInt32()
print(f"Received message: {message}") print(f"Timestamp: {timestamp}") print(f"Number: {number}") return True except Exception as e: print(f"Error reading data: {e}") return False finally: # Unlock and detach shared memory shared_memory.unlock() shared_memory.detach()
if __name__ == "__main__": if not read_shared_memory(): sys.exit(1)
Usage Instructions
-
First run the Qt C++ writer:
# Compile and run C++ programmkdir build && cd buildcmake .. && make./SharedMemoryWriter
2. Then run the Python reader (in another terminal):
pip install PySide6 # If not already installedpython SharedMemoryReader.py
Alternative: Use Native System Shared Memory
If you prefer not to rely on Qt’s Python bindings, you can implement it using Python’s standard library:
Python Reader Alternative (using posix_ipc or mmap):
import posix_ipc # Requires installation: pip install posix_ipcimport sysimport jsonfrom datetime import datetime
def read_shared_memory_native(): try: # Open existing shared memory memory = posix_ipc.SharedMemory("QtPythonSharedMemory", posix_ipc.O_CREAT)
# Read data data = memory.read() memory.close()
# Parse data (assuming data is in JSON format) decoded_data = json.loads(data.decode('utf-8'))
print(f"Received message: {decoded_data['message']}") print(f"Timestamp: {datetime.fromisoformat(decoded_data['timestamp'])}") print(f"Number: {decoded_data['number']}") return True except Exception as e: print(f"Error reading shared memory: {e}") return False
if __name__ == "__main__": if not read_shared_memory_native(): sys.exit(1)
The corresponding Qt C++ code needs to be modified to use the native shared memory API and write data in JSON format.
Notes
-
Ensure both programs use the same shared memory key
-
Consider consistency of data serialization format
-
Handle synchronization issues for concurrent access
-
Properly handle errors and exceptions
-
Ensure shared memory resources are correctly released after use
This example demonstrates how to perform basic communication between Qt C++ and Python through shared memory. Depending on actual requirements, you may need to adjust the data format or add more complex synchronization mechanisms.