SingleApplication (Linux only)

Code-Schnippsel, oder Tipps und Tricks, die einem beim Programmieren mit Qt helfen können.
Antworten
Burgpflanze
Beiträge: 89
Registriert: 24. Februar 2006 16:41
Wohnort: Dresden

SingleApplication (Linux only)

Beitrag von Burgpflanze »

singleapplication.h

Code: Alles auswählen

/***************************************************************************
 *   Copyright (C) 2007 by Peter Gaede   *
 *   develop@linux-peter.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef SINGLEAPPLICATION_H
#define SINGLEAPPLICATION_H

#include <QApplication>

class SingleApplication : public QApplication
{
	Q_OBJECT

	public:
		SingleApplication(const QString &lockFile, int &argc, char **argv);
		~SingleApplication();

		bool isRunning() const;
		QString lockFile() const;

	private:
		bool m_isRunning;
		QString m_lockFile;
		
		bool checkForRunningInstance();
};

#endif // SINGLEAPPLICATION_H
singleapplication.cpp

Code: Alles auswählen

/***************************************************************************
 *   Copyright (C) 2007 by Peter Gaede   *
 *   develop@linux-peter.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "singleapplication.h"
#include <QFile>
#include <QProcess>
#include <QWidget>
#include <QMessageBox>
#include <QDir>
#include <unistd.h>

SingleApplication::SingleApplication(const QString &lockFile, int &argc, char **argv)
	: QApplication(argc, argv)
{
	m_lockFile = QString("%1/%2").arg(QDir::tempPath()).arg(lockFile);
	m_isRunning = checkForRunningInstance();
}

SingleApplication::~SingleApplication()
{
	if (!m_isRunning)
	{
		QFile file(m_lockFile);
		if (file.exists())
			file.remove();
	}
}

bool SingleApplication::checkForRunningInstance()
{
	QFile file(m_lockFile);

	// Check if lock file exists
	if (file.exists())
	{
		// Now we check if a previous instance are running
		if (file.open(QIODevice::Text | QIODevice::ReadOnly))
		{
			QString pid = QString(file.readLine());
			file.close();

			if (!pid.isEmpty())
			{
				QProcess p;

				p.start("ps", QStringList() << "--pid" << pid);
				p.waitForFinished();

				QString data = QString(p.readAllStandardOutput());
				if (data.contains(pid))
					return true;
			}
		}
		else
		{
			QWidget w;
			QMessageBox::critical(&w, tr("Lock file error"), QString(tr("Unable to open lock file for reading:\n%1")).arg(m_lockFile));
			return true;
		}
	}

	// We are the only one instance, now we write our pid to lock file
	if (file.open(QIODevice::Text | QIODevice::WriteOnly))
	{
		file.resize(0);
		file.write(QString::number(getpid()).toAscii());
		file.close();
	}
	else
	{
		QWidget w;
		QMessageBox::critical(&w, tr("Lock file error"), QString(tr("Unable open lock file for writing:\n%1")).arg(m_lockFile));
		return true;
	}

	return false;
}

QString SingleApplication::lockFile() const
{
	return m_lockFile;
}

bool SingleApplication::isRunning() const
{
	return m_isRunning;
}
test.cpp

Code: Alles auswählen

#include "singleapplication.h"
#include <QDialog>

int main(int argc, char **argv)
{
	SingleApplication app(".singleapptest_lock", argc, argv);
	if (app.isRunning())
		return 0;
    
    QDialog d;
    d.show();

    app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
    return app.exec();
}
Gruß, Peter
hakaishi
Beiträge: 62
Registriert: 8. Dezember 2009 18:25

Beitrag von hakaishi »

Um zu überprüfen, ob ein Programm schon läuft ist das sehr viel Code...
Mit QDBus kann ich das auf eine if-Schleife in main.cpp reduzieren:

Code: Alles auswählen

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

  QApplication app(argc, argv);

  SomeClass window;

  if(QDBusConnection::sessionBus().registerService("org.example")){
    window.show();
    return app.exec();
  }
}
Nicht zu vergessen "QT += dbus" in der .pro Datei hinzuzufügen.

Wer möchte kann jetzt nach der if(...) ein else anhängen, wo man eine QMessageBox erzeugen und anzeigen lassen kann.
Man kann auch das laufende Programm anzeigen lassen, aber das ist dann schon komplexer. Wer wissen will wie das geht, kann sich bei http://doc.trolltech.com/4.5/qtdbus.html erkundigen, oder mein Programm qshutdown ansehen (wegen der Windows Kompatibilität ist es allerdings etwas unübersichtlich geworden, da es QDBus unter Windows nicht gibt).

Gruß, Hakaishi
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Oder noch einfacher mit der Qt-Solution 'QtSingleApplication' :)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
hakaishi
Beiträge: 62
Registriert: 8. Dezember 2009 18:25

Beitrag von hakaishi »

Christian81 hat geschrieben:Oder noch einfacher mit der Qt-Solution 'QtSingleApplication' :)
http://doc.trolltech.com/solutions/3/qt ... ation.html
Sieht zwar einfacher aus, als das obige Bsp., aber ich finde mit QDBus ist das genauso leicht umzusetzten... - Allerdings wird QDBus von Windows nicht unterstützt...
Antworten