2

I used in my Qt program code to avoid opening second instance:

#include "mainwindow.h"
#include <QApplication>
#include <QSharedMemory>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

        const char* MEM_KEY = "42";

        QSharedMemory sharedMem(MEM_KEY);

        if (sharedMem.create(1024)) 
        {
            qDebug() << "Create shared memory";
        } 
        else 
        {
            if (sharedMem.error() == QSharedMemory::AlreadyExists) 
            {
                qWarning() << "Already create. Exiting process";
                return 1;
            }
        }
        MainWindow w;
        w.setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);
        w.show();
        return a.exec();

It works (this code block opening second instance of my aplication [it is automatically close]), but I want to send an message or signal from opened for a moment second instance to first instance to perform for ex. maximalize window of first instance. Could you tell me how to do this simply?

km2442
  • 779
  • 2
  • 11
  • 31
  • can you please explain? I am beginner in Qt and I do not understand what your code is doing. "It works" .. what is working? I mean to "avoid opening second instance" you normally do not have to do anything (...apart from not opening a second instance) and I do not see any other instance in the code. – 463035818_is_not_an_ai Jul 16 '15 at 13:04
  • I have edited my post. Do you undersand now? – km2442 Jul 16 '15 at 13:15
  • I am not 100% sure. Do you... create some shared memory with a key (42) when the program is started for the first time. When it is created the second time, creating this shared memory will fail (because it already exists) and you exit the application... ? If yes, I have 2 comments: 1) What if some other application already created some shared mem with the same key? 2) Cant you use this shared memory to pass a message? – 463035818_is_not_an_ai Jul 16 '15 at 13:21
  • Please check @Amartel answer. It solve my problem. My code was bad :/ – km2442 Jul 16 '15 at 16:46

2 Answers2

4

You can use QtSingleApplication for this purpose. For example:

int main(int argc, char *argv[])
{
    QtSingleApplication a(argc, argv);
    if (a.isRunning())
    {
        a.sendMessage("42");
        qWarning() << "Already create. Exiting process";
        return 1;
    }

    MainWindow w;
    a.setActivationWindow(&w);
    QObject::connect(&a, SIGNAL(messageReceived(QString))
                     , &w, SLOT(onMessageReceived(QString)));
    w.show();

    int ret = a.exec();
    QObject::disconnect(&a, 0, &w, 0);
    return ret;
}

...

void MainWindow::onMessageReceived(const QString &message)
{
    // Do stuff
}
Amartel
  • 4,248
  • 2
  • 15
  • 21
-1

You are looking for IPC (inter process communication) and sadly, i don't think there is a portable way of doing this, except for creating a socket and listening on 127.0.0.1. But if you are on unix i do recommend using qdbus. That is what all the cool linux programs are doing ;)

On windows there is i believe something similar. (But this is all not built into qt.) You can find the handle of your window (HWND) and use sendmessage(). to send a custom message you'll have to declare your own WM_SECONDINSTANCE (or something similar) by:

#define WM_SECONDINSTANCE WM_USER
#define WM_SOMEOTHERMESSAGE WM_USER+1

or use an enum (i'm lazy). This tells your existing instance that another instance has been opened. To handle it in qt have a look at this.

To find the HWND, i would just put it int your shared memory from your first instance. (My windows-knowledge is a bit rusty, so sorry for any errors)

Community
  • 1
  • 1
David van rijn
  • 2,108
  • 9
  • 21