يعد هذا بديلاً لتطبيق QtSingleApplication لـ Qt5
و Qt6
.
يحتفظ بالمثيل الأساسي لتطبيقك ويقتل كل المثيلات اللاحقة. يمكنه (إذا تم تمكينه) إنشاء مثيلات ثانوية (غير مرتبطة بالأساسية) ويمكنه إرسال البيانات إلى المثيل الأساسي من المثيلات الثانوية.
يمكنك العثور على مرجع الاستخدام الكامل والأمثلة هنا.
ترث فئة SingleApplication
من فئة Q[Core|Gui]Application
التي تحددها عبر الماكرو QAPPLICATION_CLASS
( QCoreApplication
هو الإعداد الافتراضي). الاستخدام الإضافي يشبه استخدام فئات Q[Core|Gui]Application
.
يمكنك استخدام المكتبة كما لو كنت تستخدم أي فئة أخرى مشتقة من QCoreApplication
:
# include < QApplication >
# include < SingleApplication.h >
int main ( int argc, char * argv[] )
{
SingleApplication app ( argc, argv );
return app. exec ();
}
لتضمين ملفات المكتبة، أوصي بإضافتها كوحدة فرعية لـ git إلى مشروعك. هنا كيف:
git submodule add https://github.com/itay-grudev/SingleApplication.git singleapplication
قماكي:
ثم قم بتضمين ملف singleapplication.pri
في ملف مشروع .pro
الخاص بك.
include ( singleapplication/singleapplication.pri )
DEFINES += QAPPLICATION_CLASS = QApplication
كميك:
ثم قم بتضمين الدليل الفرعي في ملف المشروع CMakeLists.txt
.
set (QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication" )
add_subdirectory (src/third-party/singleapplication)
target_link_libraries ( ${PROJECT_NAME} SingleApplication::SingleApplication)
قد لا يكون تضمين هذا المستودع مباشرةً كوحدة فرعية لـ Git، أو حتى مجرد نسخة سطحية من كود المصدر في المشاريع الجديدة أمرًا مثاليًا عند استخدام CMake. هناك خيار آخر وهو استخدام وحدة FetchContent
الخاصة بـ CMake، المتوفرة منذ الإصدار 3.11
.
# Define the minumun CMake version, as an example 3.24
cmake_minimum_required ( VERSION 3.24)
# Include the module
include (FetchContent)
# If using Qt6, override DEFAULT_MAJOR_VERSION
set (QT_DEFAULT_MAJOR_VERSION 6 CACHE STRING "Qt version to use, defaults to 6" )
# Set QAPPLICATION_CLASS
set (QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication" )
# Declare how is the source going to be obtained
FetchContent_Declare(
SingleApplication
GIT_REPOSITORY https://github.com/itay-grudev/SingleApplication
GIT_TAG master
#GIT_TAG e22a6bc235281152b0041ce39d4827b961b66ea6
)
# Fetch the repository and make it available to the build
FetchContent_MakeAvailable(SingleApplication)
# Then simply use find_package as usual
find_package (SingleApplication)
# Finally add it to the target_link_libraries() section
target_link_libraries (ClientePOS PRIVATE
Qt ${QT_VERSION_MAJOR} ::Widgets
Qt ${QT_VERSION_MAJOR} ::Network
Qt ${QT_VERSION_MAJOR} ::Sql
SingleApplication::SingleApplication
)
تقوم المكتبة بإعداد QLocalServer
وكتلة QSharedMemory
. المثيل الأول لتطبيقك هو المثيل الأساسي الخاص بك. سيتحقق من وجود كتلة الذاكرة المشتركة وإذا لم يكن الأمر كذلك، فسيتم تشغيل QLocalServer
والاستماع للاتصالات. سيتحقق كل مثيل لاحق لتطبيقك من وجود كتلة الذاكرة المشتركة وإذا كان موجودًا، فسوف يتصل بـ QLocalServer لإعلام المثيل الأساسي ببدء مثيل جديد، وبعد ذلك سينتهي برمز الحالة 0
. في المثيل الأساسي، سيُصدر SingleApplication
إشارة instanceStarted()
عند اكتشاف بدء تشغيل مثيل جديد.
تستخدم المكتبة stdlib
لإنهاء البرنامج باستخدام وظيفة exit()
.
لا تنس أيضًا تحديد فئة QCoreApplication
التي يستخدمها تطبيقك إذا لم يكن QCoreApplication
كما في الأمثلة أعلاه.
تنفذ فئة SingleApplication
إشارة instanceStarted()
. يمكنك الارتباط بهذه الإشارة لرفع نافذة التطبيق الخاص بك عند بدء مثيل جديد، على سبيل المثال.
// window is a QWindow instance
QObject::connect (
&app,
&SingleApplication::instanceStarted,
&window,
&QWindow::raise
);
يعد استخدام SingleApplication::instance()
طريقة رائعة للحصول على مثيل SingleApplication
لربط إشاراته في أي مكان في برنامجك.
ملاحظة: في نظام التشغيل Windows، تكون القدرة على جلب نوافذ التطبيق إلى المقدمة مقيدة. راجع تطبيقات Windows المحددة للحصول على حل بديل ومثال للتنفيذ.
إذا كنت تريد أن تكون قادرًا على تشغيل مثيلات ثانوية إضافية (غير مرتبطة بمثيلك الأساسي)، فيجب عليك تمكين ذلك باستخدام المعلمة الثالثة لمنشئ SingleApplication
. الإعداد الافتراضي هو false
مما يعني عدم وجود مثيلات ثانوية. فيما يلي مثال لكيفية بدء مثيل ثانوي بإرسال رسالة تحتوي على وسيطات سطر الأوامر إلى المثيل الأساسي ثم إيقاف التشغيل.
int main ( int argc, char *argv[])
{
SingleApplication app ( argc, argv, true );
if ( app. isSecondary () ) {
app. sendMessage ( app. arguments (). join ( ' ' )). toUtf8 () );
app. exit ( 0 );
}
return app. exec ();
}
ملاحظة: لن يتسبب المثيل الثانوي في انبعاث إشارة instanceStarted()
افتراضيًا. راجع SingleApplication::Mode
لمزيد من التفاصيل.*
يمكنك التحقق مما إذا كان المثيل الخاص بك أساسيًا أم ثانويًا بالطرق التالية:
app.isPrimary();
// or
app.isSecondary();
ملاحظة: إذا تم إنهاء المثيل الأساسي الخاص بك، فسوف يحل المثيل الذي تم تشغيله حديثًا محل المثيل الأساسي حتى لو تم تعيين العلامة الثانوية.*
هناك ثلاثة أمثلة مقدمة في هذا المستودع:
examples/basic
examples/calculator
للنافذة الرئيسية الخاصة بهexamples/sending_arguments
يقدم كل إصدار رئيسي إما تغييرات مهمة جدًا أو غير متوافق مع الإصدار السابق. تضيف الإصدارات الثانوية فقط ميزات إضافية أو إصلاحات للأخطاء أو تحسينات في الأداء، كما أنها متوافقة مع الإصدار السابق. راجع CHANGELOG.md لمزيد من التفاصيل.
يتم تنفيذ المكتبة باستخدام كتلة QSharedMemory
وهي آمنة للسلسلة وتضمن عدم حدوث حالة سباق. كما أنه يستخدم QLocalSocket
لإعلام العملية الرئيسية بأنه قد تم إنشاء مثيل جديد وبالتالي استدعاء إشارة instanceStarted()
ولمراسلة المثيل الأساسي.
بالإضافة إلى ذلك، يمكن للمكتبة التعافي من التعرض للقتل القسري على أنظمة *nix وستعيد ضبط كتلة الذاكرة نظرًا لعدم وجود مثيلات أخرى قيد التشغيل.
يتم إصدار هذه المكتبة والوثائق الداعمة لها، باستثناء أمثلة حاسبة Qt التي يتم توزيعها بموجب ترخيص BSD، بموجب شروط The MIT License (MIT)
مع شرط إضافي، وهو:
Permission is not granted to use this software or any of the associated files
as sample data for the purposes of building machine learning models.