QT can only run one instance of 3 ways _QT

Source: Internet
Author: User
Tags emit key string message queue
Transferred from http://blog.csdn.net/robertkun/article/details/8518576

1. Methods of shared memory
Unix:qsharedmemory "owns" the Shared memory segment. When the "last thread or process" has an instance of qsharedmemory attached to a particular shared memory segment Detac Hes from the segment by destroying its instance of Qsharedmemory, the Unix kernel release the shared memory segment. But if that is last thread or process crashes without running the Qsharedmemory destructor, the shared memory segment s the crash.
(It is said that this method will have a memory release problem under the Linux system, which in some cases can cause the program to be abnormal or crash)

   
Make sure to run only once   
  
Qsystemsemaphore sema ("Jamkey", 1,qsystemsemaphore::open);   
Sema.acquire ()//operation of shared memory   sharedmemory   
  
qsharedmemory mem ("SystemObject") in critical section;//Global Object name   
if (!mem.create (1 )//If the global object exits   
{   
    qmessagebox::information (0, Messageboxtxt, "an instance has already been.");  
   
    Sema.release ();//If it is a Unix system, it will be automatically released. return   
  
    0;   
}   
  
Sema.release ();//Critical area

2. Use of Qlocalserver and Qlocalsocket classes
Here is the code written by yourself, mainly when running the second instance, there is a hint of the role:
1. Switch to the current program and display the current program maximized to the front.
2. Close the process of the current program and open the new program.
(Note: Need to add QT + network in your. Pro)

Header file

[CPP] View plain copy #ifndef psa_usr_login_h #define Psa_usr_login_h #include <QDialog> #include <qtime line> #include <QLocalServer> #include "ui_dlgusrlogin.h" #define PROCESS_SHOW 1 #define PRO  
Cess_restart 2 #define PROCESS_STOP 3 const QString pro_show = "Pro_show";  
Const QString Pro_restart = "Pro_restart";  
  
Const QString pro_stop = "Pro_stop"; Class Cusrlogin:public Qdialog {q_object public:cusrlogin (const qstring& serverName, qwidget* p  
    arent = NULL);  
  
    Virtual ~cusrlogin ();  
    int getindex () const;  
  
BOOL Initserver ();  
  
Signals:void Sig_neworder (const qstring&);  
    Private Slots:void SLOT_OK ();  
    void Slot_cancel ();  
    void slot_btngroupclicked (int);  
    void Slot_newconnection ();  
    void Slot_readyread ();  
  
void Slot_timefinished ();  
  
Private:int isserverrun (const QString & servername); Private  
    UI::D Lgusrlogin UI;  
    int mindex;  
    QString Mservername;  
    qlocalserver* Mpserver;  
Qtimeline *mptimeline;  
  
}; #endif

source files

[CPP] View plain copy #include "psa_usr_login.h" #include <QButtonGroup> #include <QLocalSocket> cusr Login::cusrlogin (const qstring& serverName, qwidget* parent/*= null*/): Qdialog (parent), Mpserver (NUL  
  
    L), Mptimeline (NULL) {ui.setupui (this);  
    Mindex = 1;  
  
    Mservername = ServerName;  
    qbuttongroup* btngroup = new Qbuttongroup;  
    Btngroup->addbutton (Ui.btn_showcurpro, process_show);  
  
    Btngroup->addbutton (Ui.btn_opennewpro, Process_restart);  
    Ui.progressbar->setvisible (FALSE);  
    Mptimeline = new Qtimeline (3000, this);  
    Mptimeline->setframerange (0, 100);  
    Connect (Mptimeline, SIGNAL (framechanged (int)), Ui.progressbar, SLOT (int));  
  
    Connect (Mptimeline, SIGNAL (finished ()), this, SLOT (slot_timefinished ()));  
    Connect (Btngroup, SIGNAL (buttonpressed (int)), this, SLOT (slot_btngroupclicked (int))); Connect (UI.BTN_OK, SIGNAL (clicked ()), this, SLOT (slot_oK ()));  
Connect (Ui.btn_cancel, SIGNAL (clicked ()), this, SLOT (Slot_cancel ()));  
        } cusrlogin::~cusrlogin () {if (mpserver) {qlocalserver::removeserver (mservername);  
        Delete Mpserver;  
    Mpserver = NULL;  
        } if (Mptimeline) {mptimeline->stop ();  
        Delete Mptimeline;  
    Mptimeline = NULL;  
} int Cusrlogin::getindex () const {return mindex;  
    } void Cusrlogin::slot_ok () {qlocalsocket ls;  
  
    Ls.connecttoserver (Mservername);  
                if (ls.waitforconnected ()) {switch (mindex) {case process_show: {  
                Char msg[25] = {0};  
                memcpy (MSG, pro_show.tostdstring (). C_STR (), pro_show.length ());  
                Ls.write (msg);  
  
                Ls.waitforbyteswritten ();  
                Qdialog::accept ();  
            Break  
    Case Process_restart:        {char msg[25] = {0};  
                memcpy (MSG, pro_restart.tostdstring (). C_STR (), pro_restart.length ());  
                Ls.write (msg);  
  
                Ls.waitforbyteswritten ();  
                Ui.progressbar->setvisible (TRUE);  
                Mptimeline->start ();  
            Break  
                Case Process_stop: {char msg[25] = {0};  
                memcpy (MSG, pro_stop.tostdstring (). C_STR (), pro_stop.length ());  
                Ls.write (msg);  
  
                Ls.waitforbyteswritten ();  
                Qdialog::accept ();  
            Break  
            } default:qdialog::accept ();  
        Break  
}} void Cusrlogin::slot_cancel () {qdialog::reject ();  
} void cusrlogin::slot_btngroupclicked (int idx) {mindex = idx; } void Cusrlogin::slot_readyread () {Qlocalsocket *local = Static_cAst<qlocalsocket *> (Sender ());  
  
    if (!local) return;  
    Qtextstream in (local);  
  
    QString readmsg;  
  
    Readmsg = In.readall ();  
Emit Sig_neworder (readmsg);   
    //Determine if there is a server with the same name running int cusrlogin::isserverrun (const QString & servername) {Qlocalsocket ls;  
  
    Ls.connecttoserver (servername);  
        if (ls.waitforconnected (1000)) {ls.disconnectfromserver ();  
        Ls.close ();  
    return 1;  
return 0; BOOL Cusrlogin::initserver () {if (!  
        Isserverrun (Mservername)) {mpserver = new Qlocalserver;  
  
        Qlocalserver::removeserver (Mservername);  
        Mpserver->listen (Mservername);  
  
        Connect (Mpserver, SIGNAL (Newconnection ()), this, SLOT (Slot_newconnection ()));  
    return true;  
return false; } void Cusrlogin::slot_newconnection () {Qlocalsocket *newsocket = Mpserver->nextpendingconneCtion ();  
Connect (Newsocket, SIGNAL (Readyread ()), this, SLOT (Slot_readyread ()));  
    } void Cusrlogin::slot_timefinished () {if (Initserver ()) {qdialog::accept ());   }  
}


Main function:
Add Cusrlogin to the main function ... and signal slot functions.

[CPP] View plain copy int main (int argc, char * argv[]) {qapplication app (argc, argv); QString name = "Hu Jintao"; The custom program name if (!login.  
        Initserver ()) {int ret = login.exec (); if (qdialog::accepted = = ret) {if (login).  
                GetIndex () = = Process_show | | Login.  
            GetIndex () = = Process_stop) {return 1;  
        } else {return 1;  
    } MainWindow Mainwin;  
  
Mainwin.show ();  
            Implementation in MainWindow: [CPP] View plain Copy {if (order = = pro_show) {#ifdef WIN32 {  
            Activatewindow ();  
            Showminimized ();  
        Showmaximized ();  
  
            } #else {Activatewindow (); if (WindowState () & qt::windowminimized) {setwindowstate (WindowState () & ~ Qt::windowminimizEd |  
                    qt::windowactive);  
                    Showmaximized ();  
            Show (); else if (WindowState () & qt::windowmaximized) {setwindowstate (w Indowstate () & qt::windowmaximized |  
            qt::windowactive); else {setwindowstate windowstate () & qt::windowmaximized |  
            qt::windowactive);  
    #endif} else if (order = = Pro_restart) {close ();  
    else if (order = = Pro_stop) {close (); 
 }  
}


3. Qsingleapplication class
The principle of implementation should be the same as Qlocalserver and Qlocalsocket.
Use the Qsharedmemory,qlocalserver and Qlocalsocket implementations in QT (though you need to add QT + network to your. Pro)
The details are as follows:
An introduction
By writing a qsingleapplication class to implement a single case of QT program, the author of the original is implemented under Windows Vista +qt4.4, but it is not a problem to apply to other platforms. (This is what I saw on the http://www.qtcentre.org/wiki/index.php?title=SingleApplication.)

Two code
Scenario One: Use QT Qsharedmemory,qlocalserver and Qlocalsocket implementations (but add QT + network to your. Pro)

Other no translation, is probably said a bit, directly to the code:

"Single_application.h" #ifndef single_application_h #define SINGLE_APPLICATION_H #include <QApplication> Include <QSharedMemory> #include <QLocalServer> class singleapplication:public qapplication {q_object PU
	blic:singleapplication (int &argc, char *argv[], const QString uniquekey);
	BOOL IsRunning ();
BOOL SendMessage (const QString &message);
Public slots:void receivemessage ();
Signals:void messageavailable (QString message);
	Private:bool _isrunning;
	QString _uniquekey;
	Qsharedmemory sharedmemory;
	Qlocalserver *localserver;
static const int timeout = 1000;

}; #endif//Single_application_h//"single_application.cpp" #include <QLocalSocket> #include "single_ Application.h "singleapplication::singleapplication (int &argc, char *argv[], const QString UniqueKey):
	Qapplication (argc, argv), _uniquekey (UniqueKey) {Sharedmemory.setkey (_uniquekey);
	if (Sharedmemory.attach ()) _isrunning = true;
		else {_isrunning = false;Create shared memory.
			if (!sharedmemory.create (1)) {Qdebug ("Unable to create a single instance.");
		Return
		The//create local server and listen to incomming messages from the other instances.
		LocalServer = new Qlocalserver (this);
		Connect (LocalServer, SIGNAL (Newconnection ()), this, SLOT (ReceiveMessage ()));
	Localserver->listen (_uniquekey);
}//Public slots.
	void Singleapplication::receivemessage () {Qlocalsocket *localsocket = localserver->nextpendingconnection ();
		if (!localsocket->waitforreadyread (timeout)) {Qdebug (Localsocket->errorstring (). ToLatin1 ());
	Return
	} Qbytearray ByteArray = Localsocket->readall ();
	QString message = Qstring::fromutf8 (Bytearray.constdata ());
	Emit messageavailable (message);
Localsocket->disconnectfromserver ();
}//Public functions.

BOOL Singleapplication::isrunning () {return _isrunning;}
	BOOL Singleapplication::sendmessage (const QString &message) {if (!_isrunning) return false; QlocalsocketLocalsocket (this);
	Localsocket.connecttoserver (_uniquekey, qiodevice::writeonly);
		if (!localsocket.waitforconnected (timeout)) {Qdebug (Localsocket.errorstring (). ToLatin1 ());
	return false;
	} localsocket.write (Message.toutf8 ());
		if (!localsocket.waitforbyteswritten (timeout)) {Qdebug (Localsocket.errorstring (). ToLatin1 ());
	return false;
	} localsocket.disconnectfromserver (); return true;


Scenario Two: Use Qt qsharedmemory, and qtimert implementation, no other translation, or directly to the code bar:

"Single_application.h" #ifndef single_application_h #define SINGLE_APPLICATION_H #include <QApplication> Include <QSharedMemory> class Singleapplication:public qapplication {q_object public:singleapplication (int &A
	MP;ARGC, Char *argv[], const QString uniquekey);
	BOOL IsRunning ();
BOOL SendMessage (const QString &message);
Public slots:void checkformessage ();
Signals:void messageavailable (QString message);
	Private:bool _isrunning;
Qsharedmemory sharedmemory;

}; #endif//Single_application_h//"single_application.cpp" #include <QTimer> #include <QByteArray> #include "Single_application.h" singleapplication::singleapplication (int &argc, char *argv[], const QString UniqueKey):
	Qapplication (argc, argv) {Sharedmemory.setkey (UniqueKey);
	if (Sharedmemory.attach ()) _isrunning = true;
		else {_isrunning = false;
		Attach data to shared memory. Qbytearray ByteArray ("0");
	The ' default value to ' Note ' No ' is available.	if (!sharedmemory.create (Bytearray.size ())) {Qdebug ("Unable to create single instance.");
		Return
		} sharedmemory.lock ();
		Char *to = (char*) sharedmemory.data ();
		const char *from = Bytearray.data ();
		memcpy (To, from, Qmin (Sharedmemory.size (), Bytearray.size ()));

                Sharedmemory.unlock ();
		Start checking for messages of the other instances.
		Qtimer *timer = new Qtimer (this);
		Connect (timer, SIGNAL (timeout ()), this, SLOT (Checkformessage ()));
	Timer->start (1000);
}//Public slots.
	void Singleapplication::checkformessage () {sharedmemory.lock ();
	Qbytearray ByteArray = Qbytearray ((char*) Sharedmemory.constdata (), sharedmemory.size ());
	Sharedmemory.unlock ();
	if (bytearray.left (1) = = "0") return;
	Bytearray.remove (0, 1);
	QString message = Qstring::fromutf8 (Bytearray.constdata ());

        Emit messageavailable (message);
	Remove message from shared memory.
	ByteArray = "0";
	Sharedmemory.lock ();
	Char *to = (char*) sharedmemory.data (); Const CHar *from = Bytearray.data ();
	memcpy (To, from, Qmin (Sharedmemory.size (), Bytearray.size ()));
Sharedmemory.unlock ();
}//Public functions.

BOOL Singleapplication::isrunning () {return _isrunning;}

	BOOL Singleapplication::sendmessage (const QString &message) {if (!_isrunning) return false;
	Qbytearray ByteArray ("1");
	Bytearray.append (Message.toutf8 ()); Bytearray.append ('/0 ');
	< should as Char here, not a string!
	Sharedmemory.lock ();
	Char *to = (char*) sharedmemory.data ();
	const char *from = Bytearray.data ();
	memcpy (To, from, Qmin (Sharedmemory.size (), Bytearray.size ()));
	Sharedmemory.unlock ();
return true; }


Three use

"Main.cpp"
#include "single_application.h"
int main (int argc, char *argv[])
{
	singleapplication App (argc, argv, "some unique key string");
	if (app.isrunning ())
	{
		app.sendmessage ("message from other instance.");
		return 0;
	}

	MainWindow *mainwindow = new MainWindow ();

        Connect message queue to the main window.
	Qobject::connect (&app, SIGNAL (messageavailable (QString)), MainWindow, SLOT (ReceiveMessage (QString)));

        Show MainWindow.
	Mainwindow->show ();
	return app.exec ();

}





Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.