1 year ago
#71527
ddgg
Share an instance of a QMainWindow through shared memory
Is it possible to share an instance of an QMainWindow
(or a QWidget
) through QSharedMemory
?
I have been looking for some examples, and as far as I understood the problem seems to be that the QDataStream&operator>>
doesn't know how to deserialise a QObject
...right?
here my attempt: I serialise and copy the instance of my MainWindow
into the shared memory
void MainWindow::loadIntoMemory()
{
...
QBuffer buffer;
buffer.open(QBuffer::WriteOnly);
QDataStream out(&buffer);
... // omitting - if this == nullptr -
out << this; // <-- serialising the MainWindow
int size = buffer.size();
sharedMemory.create(size)); // omitting if statement to avoid post verbosity
sharedMemory.lock();
char *to = (char*)sharedMemory.data();
const char *from = buffer.data().data();
memcpy(to, from, qMin(sharedMemory.size(), size));
...
}
but it comes to deserialise it from another app:
QMainWindow parentApp;
QBuffer buffer;
QDataStream in(&buffer);
in >> parentApp;
I got the error: error: invalid operands to binary expression ('QDataStream' and 'QMainWindow') qchar.h:663:28: note: candidate function not viable: no known conversion from 'QMainWindow' to 'QChar &' for 2nd argument
.
I have been also considering that maybe sharing the memory address of this
could be an option. Something like:
- saving
this
(aQMainWindow*) as a
QbitArray` - serialise it
- copying into the shared memory and load it from another application
but I wouldn't know how to do it...
EDIT
The ultimate goal of this Application would be the following:
The Application "A" (the one reading from the shared memory) is a child process (QProcess
) of Application "B" (the one writing into the shared memoery). Application "A" is able to dynamically instantiate QDockWidget
s which should dock onto the MainWindow
of Application "B".
Since I cannot access any parent element from a child process, I was considering to share the Application "B"'s MainWindow
from a shared memory and instantiate:
QDockWidget dock = new QDockWidget(parentAppMainWindow) // pointer red from the QSharedMemory
EDIT (second step):
As suggested by @G.M. one possible approach is to exchange the window id by (in this case) a shared memory. So I refactored the above presented loadIntoMemory
function so that "Application B" (the parent) shared its MainWindow
'id
into the shared memory :
void MainWindow::loadIntoMemory() // from application B
{
// I instantiate "out" as QDataStream using the QBuffer buffer (Write only)
...
WId id = this->winId();
out << id; // <-- serialize id into the QDataStream
qDebug() << id // print the id
...
// calculate the size of the buffer and memcpy buffer into the
}
then I read the value from sharedMemory
from Application A
(the child
Qprocess
of Application B
as follows:
WId parentWinId;
QBuffer buffer;
QDataStream in(&buffer); // read the id
sharedMemory.lock();
buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
buffer.open(QBuffer::ReadOnly);
in >> parentWinId;
sharedMemory.unlock();
qDebug() <<"The parent window Id is" << parentWinId; // parentWinId has exactly the same id as in the previous code block
qDebug() << "Here a representation of the parent window " << QWindow::fromWinId(parentWinId); // CRASH
but "Application A" crashes.
Thank you very much for your support!
c++
qt
shared-memory
0 Answers
Your Answer