সিগন্যাল কল করে এমিট বনাম ব্যবহার করা যেমন এটি Qt এ নিয়মিত কাজ


97

ধরা যাক আমার এই সংকেত রয়েছে:

signals:
    void progressNotification(int progress);

আমি সম্প্রতি Qt এ এমিট কীওয়ার্ড সম্পর্কে শিখেছি। এখন অবধি, আমি কেবল নিয়মিত ফাংশনের মতো কল করে সংকেতগুলি প্রয়োগ করতাম। এর পরিবর্তে:

emit progressNotification(1000 * seconds);

আমি লিখব:

progressNotification(1000 * seconds);

তাদের যেমন কল করা কাজ বলে মনে হয়েছিল, এবং সমস্ত সংযুক্ত স্লট কার্যকর হয়ে যাবে, তাই কি এমিট কীওয়ার্ড ব্যবহার করে কোনও আলাদা আচরণের কারণ হয়, না এটি কেবল সিনট্যাকটিক চিনির?


17
+1 কখনই জানতেন emitযে প্রয়োজন নেই। যদিও এটি আশ্চর্যের বিষয় নয় যে, আপনি emitসরাসরি সিগন্যাল কল করার পরে দীর্ঘ সম্পর্কে শিখলেন , কেননা সিগন্যাল-স্লট সিস্টেমটি কিউটি সম্পর্কে প্রথম জানা জিনিসগুলির মধ্যে একটি।
খ্রিস্টান রাউ

উত্তর:


89

emitশুধু সিনট্যাকটিক চিনি। আপনি যদি সিগন্যাল নির্গত করে এমন ফাংশনটির প্রাক-প্রক্রিয়াজাত আউটপুটটি দেখে থাকেন emitতবে আপনি দেখতে পাবেন যে সবেমাত্র চলে গেছে।

"যাদু" সংকেত নির্গমন ফাংশনের জন্য উত্পন্ন কোডে ঘটে যা আপনি মোক দ্বারা উত্পাদিত সি ++ কোড পরিদর্শন করে দেখতে পারেন।

উদাহরণস্বরূপ, কোনও fooপরামিতিবিহীন সংকেত এই সদস্যটির কার্যকারিতা উত্পন্ন করে:

void W::foo()
{
    QMetaObject::activate(this, &staticMetaObject, 0, 0);
}

এবং কোডটি emit foo();সহজভাবে প্রাক প্রক্রিয়াজাত করা হয়foo();

emitQt/qobjectdefs.h(যাইহোক উত্সের মুক্ত উত্স স্বাদে) এ সংজ্ঞায়িত করা হয়েছে :

#ifndef QT_NO_EMIT
# define emit
#endif

(সংজ্ঞায়িত no_keywordsপ্রহরীটি আপনাকে অন্য ফ্রেমওয়ার্কগুলির সাথে কিউটি ব্যবহারের অনুমতি দেয় যা QMake কনফিগারেশন বিকল্পের মাধ্যমে সংঘর্ষের নাম রয়েছে ))


14
আপনি কি জানেন emitযে বাস্তবে কখনও কিছুই না করে এমন কোনও বাস্তবায়ন (বা পরিকল্পনাযুক্ত বাস্তবায়ন) হয়েছিল কিনা ? আমি দেখতে পেয়েছি যে এই ক্ষেত্রে 'সিনট্যাকটিক চিনি' থাকার কারণে কেবল নবজাতককে বিভ্রান্ত করা হয়েছে (বা কমপক্ষে আমাকে যখন আমি একজন শিক্ষানবিশ কিউটি ব্যবহারকারী ছিলাম) - এটি প্রদর্শিত হয় যে emitছদ্ম-কীওয়ার্ডের সাথে যাদু বা গুরুত্বপূর্ণ কিছু ঘটছে , যখন এটি কিছুই করে না সমস্ত - সমস্ত যাদুটি নিয়মিত পুরানো ফাংশনে ঘটে যা mocতৈরি করে ( mocএটি কিউটি সংকেত এবং স্লটগুলির জন্য যাদু)। emitঅপ্রয়োজনীয় সাজসজ্জা যা গুরুত্বপূর্ণ মনে হলেও কিছুই করে না।
মাইকেল বুড়

12
নির্গত হয় না "শুধু প্রসাধন"। emitকলটি পড়া ব্যক্তিটিকে বলছেন যে যাদুটি ঘটতে চলেছে (যেমন এটি এই শ্রেণীর সম্ভাব্যরূপে শুনেনি এমন কোনও বস্তুগুলিতে কোড ট্রিগার করতে চলেছে, এবং এই কলগুলি সমকালীন বা অ্যাসিনক্রোনাস হতে পারে), আপনি মূল শব্দটি বাদ দিলে মূলত সম্পূর্ণরূপে হারিয়ে যায়। এটা ব্যবহার করো. এটি অটো-ডকুমেন্টিং। "নোভিসস" এর ডক্স এবং টিউটোরিয়ালগুলি পড়া উচিত এবং emitসর্বদা সেখানে থাকে (যাইহোক সরকারী ডক্সে)। আপনি "আলো দেখেন" - এর পরে আপনি যে ফাংশনটি স্রেফ কল করতে পারবেন তা আবিষ্কার করা উচিত - আপনি সেই সময়ে আর কোনও শিক্ষানবিশ নন।
মাদুর

19
হুম, আমি নিশ্চিত নই যে emit'কীওয়ার্ড' কতটা মূল্যবান সে সম্পর্কে আমি আপনার সাথে একমত । আমি মনে করি যে আমি একটি নামকরণ কনভেনশন ব্যবহার করতে পছন্দ করতাম যদি কোনও ফাংশন কল একটি সংকেত বলে পরিষ্কার করার প্রয়োজন হয়।
মাইকেল বুড়

4
ঠিক আছে, আমি এর সাথে মূলত একমত নই :) নামকরণের কনভেনশন জোর করা এমন কিছু যা আপনি নিজের প্রকল্পগুলিতে / কর্মক্ষেত্রে নিজেই করতে পারেন, Qt এটিকে আটকাবে না। Qt আপনাকে "কীওয়ার্ড" ব্যবহার করতে বাধ্য করে না, এমনকি এটি যদি আপনার কোডের অন্যান্য অংশের সাথে সংঘর্ষ হয় তবে আপনাকে এটিকে বন্ধ করার অনুমতি দেয়। আমার মতে, কীওয়ার্ডের পদ্ধতির আরও ভাল - সংকলক আপনাকে নামকরণ নীতিমালা কার্যকর করতে সহায়তা করতে পারে না, তবে এটি একটি বানান ভুল বানান emit
মাদুর

15
স্পষ্ট করে বলার জন্য - আমি নামকরণের কনভেনশনটি ব্যবহার করার পক্ষে পরামর্শ দিচ্ছিলাম না - কেবলমাত্র যদি কোনও emitসিউইডো-কীওয়ার্ড-মন্তব্য করার কারণটি যদি স্পষ্ট করে দেয় যে সংকেত আহ্বান করা হচ্ছে, তবে একটি নামকরণ কনভেনশনও একই কাজ করতে পারে, কোনটি ছাড়াই রহস্য এবং অনুরূপ সুবিধার সাথে। নামকরণ কনভেনশন Qt দ্বারা প্রয়োগ করা যায় নি (আসলে, mocএটি প্রয়োগ করতে পারে - তবে আমি এটির পক্ষেও পরামর্শ দিচ্ছি না), তবে কিউটি কোনওটির প্রয়োগ কার্যকর করতে পারে না emitemitকোনও নাম সংঘর্ষের পরেও আপনি 'বন্ধ' করতে পারেন, আপনার কাছে এমন কিছু উত্স ফাইল রয়েছে যা এটি ব্যবহার করছে (অকারণে, বুট করার জন্য) যদি এটি ব্যবহার করে না।
মাইকেল বুড়

2

18 মাস পরে ... আমি @ ম্যাট এর উত্তরে মন্তব্য দিয়ে শুরু করেছি এবং দ্রুত ঘর থেকে বেরিয়ে এসেছি। এইভাবে উত্তর।

আইএমও emitকোনও সিনট্যাকটিক চিনির মতো নয় বা এই অর্থে কোনও সাধারণ কীওয়ার্ড নয়

  1. এটি কোড উত্পন্ন করে (উপরে @ ম্যাট দ্বারা ব্যাখ্যা হিসাবে),
  2. এটি connectপ্রক্রিয়াটি বুঝতে সাহায্য করে যে সত্যই এটি একটি signal, এবং
  3. এটি আপনার সিগন্যালটিকে একটি "বৃহত্তর" সিস্টেমের অংশে পরিণত করে, যেখানে সংকেতটি কোথায় এবং কীভাবে নির্গমন হয়েছিল তার উপর নির্ভর করে সংকেত এবং প্রতিক্রিয়াগুলি (স্লট) একযোগে বা অবিচ্ছিন্নভাবে কার্যকর করা যেতে পারে বা সারি করা যেতে পারে। এটি সিগন্যাল / স্লট সিস্টেমের একটি অত্যন্ত দরকারী বৈশিষ্ট্য।

পুরো সিগন্যাল / স্লট সিস্টেমটি সাধারণ ফাংশন কলের চেয়ে আলাদা আইডিয়াম। আমি বিশ্বাস করি এটি পর্যবেক্ষক নিদর্শন থেকে উদ্ভূত। এখানে একটা মধ্যবর্তী একটি প্রধান পার্থক্য নেই signalএবং slot: একটি সংকেত নেই , বাস্তবায়ন হবে যেহেতু একটি স্লট হতে হবে !

আপনি রাস্তায় হাঁটছেন এবং একটি ঘর আগুনে দেখছেন (একটি সংকেত)। আপনি 911 ডায়াল করুন ( 911 প্রতিক্রিয়া স্লটের সাথে ফায়ার সিগন্যালটি সংযুক্ত করুন )। সংকেতটি কেবলমাত্র নির্গত হয়েছিল , যেখানে স্লটটি ফায়ার বিভাগ দ্বারা প্রয়োগ করা হয়েছিল । অসম্পূর্ণ হতে পারে, তবে আপনি ধারণা পেতে পারেন। ওপির উদাহরণটি দেখি।

কিছু ব্যাকএন্ড অবজেক্ট জানে কত অগ্রগতি হয়েছে। সুতরাং এটি কেবল emit progressNotification(...)সংকেত পারে । এই সংকেতটি তুলে নেওয়ার জন্য এটি চালিয়ে যাওয়া প্রকৃত অগ্রগতি বারটি প্রদর্শন করে class তবে দৃশ্যটি এই সংকেতের সাথে কীভাবে সংযুক্ত হবে? Qt এর সিগন্যাল / স্লট সিস্টেমে আপনাকে স্বাগতম। এখন কোনও পরিচালক শ্রেণি (সাধারণত ধরণের উইজেট) ধারণ করতে পারে, যা একটি ভিউ অবজেক্ট এবং ডেটা গণনা অবজেক্ট (উভয়ই সত্তা QObjects) নিয়ে গঠিত হতে পারে connect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)

আসুন ম্যানেজার শ্রেণির নকশার দিকগুলিতে notুকে পড়ুন না, তবে এটি যথেষ্ট বলে দিন যে এখানেই সিগন্যাল / স্লট সিস্টেমটি জ্বলজ্বল করে। আমি আমার অ্যাপ্লিকেশনটির জন্য খুব পরিষ্কার আর্কিটেকচার ডিজাইনের উপর ফোকাস করতে পারি। সবসময় নয়, তবে প্রায়শই আমি খুঁজে পাই যে আমি কেবল সংকেত নিঃসৃত করি তবে স্লট বাস্তবায়ন করি

যদি কখনও সিগন্যাল পদ্ধতিটি নির্গমন না করে ব্যবহার করা / কল করা সম্ভব হয় তবে এটি অগত্যা বোঝায় যে আপনার প্রথমে সিগন্যাল হিসাবে সেই ক্রিয়াকলাপটির প্রয়োজন ছিল না


6
না, emitপ্রকৃতপক্ষে কেবল একটি খালি ম্যাক্রো এবং খাঁটি alচ্ছিক। কীওয়ার্ডগুলি হয় না signalএবং slotযা মোক দ্বারা প্রক্রিয়া করা হয়। signalফাংশনটির বাস্তবায়ন সরবরাহ slotকরতে ব্যবহৃত হয়, মেটা অবজেক্ট এন্ট্রি তৈরি করতে ব্যবহৃত হয় তাই এটি SLOT(MySlot())ম্যাক্রোর সাথে বা কিউএমএলে পাওয়া যায় । emitসিনট্যাকটিক সুগার। আপনি কিছু লিখলে কখনও অভিযোগ করবে না emit i++;(তবে সম্ভবত আপনার সহকর্মীরা) এবং আপনি এখনও সংযোগ করতে পারবেন না i++
derM

-4

দ্বিতীয় বিকল্পটি বোঝায় যে আপনি সর্বদা ফাংশনটির নাম এবং ফাংশন পরামিতিগুলি কী তা জানেন এবং আপনি যে অবজেক্টটিতে এটি পাঠাচ্ছেন সেটি সেই নির্দিষ্ট ফাংশন দ্বারা পরিচিত। এই দুটি ক্ষেত্রে সর্বদা সত্য হয় না, সুতরাং স্লট এবং সিগন্যাল কেন তৈরি করা হয়েছিল তা মূলত দুটি বিষয়। "আন্ডার-দ্য হুড" সিগন্যাল এবং স্লট মেকানিজম কেবল সংযুক্ত প্রতিটি ফাংশনের পয়েন্টার সহ একটি টেবিল।

এছাড়াও, এই PDF যা খুবই পরিষ্কারভাবে সিগন্যাল ও স্লট প্রক্রিয়া প্রকৃতি ব্যাখ্যা তাকান: http://www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf


উভয় উপায়ে সিগন্যালের নাম এবং এর পরামিতিগুলি জানতে হবে - আপনি এটি নির্গত করছেন, আপনি কী জানেন না এমন কিছু কীভাবে নির্গত করতে পারেন? উভয়েরও একই শব্দার্থকতা রয়েছে, তারা অভিন্ন।
মাদুর

4
হয়তো আপনি সরাসরি স্লট কল দিয়ে সিগন্যাল কলটি জগাখিচুড়ি করছেন? তবে আমাকে স্বীকার করতে হবে যে আমি প্রথমে প্রশ্নের শিরোনাম সম্পর্কেও ভেবেছিলাম, যেহেতু আমি কখনই জানতাম না যে emitএটি কেবল কোনও অনিপশন ছিল না। তবে এই ক্ষেত্রেও প্রশ্ন সংস্থার পড়াগুলি বিষয়গুলি পরিষ্কার করা উচিত ছিল, তাই -১।
খ্রিস্টান রাউ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.