PDA

View Full Version : سوال: نحوه استفاده بلاک Try,Catch در Qt



returnx
چهارشنبه 09 فروردین 1391, 19:47 عصر
روش استفاده درست Try Catch در Qt به چه شکل هست!؟
من به روش زیر استفاده کردم اما هیچ تفاوتی با استاده نکردنش نداشت و خطا نمایش داده شد:
//Open File Dialog
QString ext_list="*.jpg\n*.bmp\n*.gif";
//Get File name & show Picture
file_name=QFileDialog::getOpenFileNames(this,"Open File",QDir::currentPath(),ext_list);
try
{
count=file_name.count();
index=0;
QImage image(file_name.at(index));

//Show Image Information
ui->label->setPixmap(QPixmap::fromImage(image));
ui->lbl_address->setText(file_name.at(index));
ui->lbl_width->setText(QString::number(image.width()));
ui->lbl_height->setText(QString::number(image.height()));
ui->lbl_size->setText(QString::number(image.byteCount())+" Byte");
}//End Try
catch (...)
{
QMessageBox msgbox;
msgbox.setText("No File Selected");
msgbox.exec();
}//End Catch

البته بعد از جستجو متوجه شدم که ظاهرا این روش در Qt جواب نمیده و از روش زیر استفاده کردم اما بازم جواب نداد:
catch (QFileDialog &dlg_ex)
{
QMessageBox msgbox;
msgbox.setText("No File Selected");
msgbox.exec();
}//End Catch

alamate_aoal
چهارشنبه 09 فروردین 1391, 23:49 عصر
نیازی به ستفاده از try/catch نیست

متد زیر رو بعد از ()getOpenFileNames فراخوانی کن

if( file_name.isEmpty() )
return;

mousamk
پنج شنبه 10 فروردین 1391, 13:36 عصر
شما try/catch رو جایی میتونین استفاده کنین که واقعا یک exception موقع خطا throw شود.
لایببری کیوت از این مکانیسم try/catch استفاده نمیکنه و هیچجا exceptionی throw نمیکنه، و به جای اون از همون روش قدیمی برگرداندن کد خطا یا مقدار نامعتبر (خالی یا NULL) استفاده میکنه و بنابراین شما اگه کد کیوت رو داخل try/catch بذارین هم اتفاق خاصی نمیفته.
در نتیجه تو کیوت وقتی دارین از یه تابعی استفاده میکنین که نیاز به چک کردن حالات خاص داره، باید مستندش رو نگاه کنین تا ببینین چطوری میشه این کارو کرد.
مثلا تو این مثال شما، به همون روشی که دوستمون alamate_aoal (http://barnamenevis.org/member.php?103489-alamate_aoal) گفتن باید عمل کنین.

returnx
پنج شنبه 10 فروردین 1391, 16:03 عصر
شما try/catch رو جایی میتونین استفاده کنین که واقعا یک exception موقع خطا throw شود.
لایببری کیوت از این مکانیسم try/catch استفاده نمیکنه و هیچجا exceptionی throw نمیکنه، و به جای اون از همون روش قدیمی برگرداندن کد خطا یا مقدار نامعتبر (خالی یا NULL) استفاده میکنه و بنابراین شما اگه کد کیوت رو داخل try/catch بذارین هم اتفاق خاصی نمیفته.
در نتیجه تو کیوت وقتی دارین از یه تابعی استفاده میکنین که نیاز به چک کردن حالات خاص داره، باید مستندش رو نگاه کنین تا ببینین چطوری میشه این کارو کرد.
مثلا تو این مثال شما، به همون روشی که دوستمون alamate_aoal (http://barnamenevis.org/member.php?103489-alamate_aoal) گفتن باید عمل کنین.
ممنون،جواب کاملی بود...
اما در برنامه ها بعضا خطاهایی ممکنه اتفاق بیفته که قابل پیشبینی نیست...
در Qt برای مدیریت این خطا ها چه ابزاری وجود داره!؟
آیا کلاسی برای مدیریت خطاها وجود داره!؟

mousamk
پنج شنبه 10 فروردین 1391, 16:26 عصر
ممنون،جواب کاملی بود...
اما در برنامه ها بعضا خطاهایی ممکنه اتفاق بیفته که قابل پیشبینی نیست...
در Qt برای مدیریت این خطا ها چه ابزاری وجود داره!؟
آیا کلاسی برای مدیریت خطاها وجود داره!؟

والا من که چیزی به ذهنم نمیرسه.
اگه یه مثال از همچین حالتی بدین شاید بتونم جوابی بدم.

حامد مصافی
پنج شنبه 10 فروردین 1391, 18:34 عصر
ممنون،جواب کاملی بود...
اما در برنامه ها بعضا خطاهایی ممکنه اتفاق بیفته که قابل پیشبینی نیست...
در Qt برای مدیریت این خطا ها چه ابزاری وجود داره!؟
آیا کلاسی برای مدیریت خطاها وجود داره!؟
خیر، موردی که فرمودید فقط در محیط‌های مدیریت شده مانند دات‌نت و جاوا وجود دارد

alamate_aoal
پنج شنبه 10 فروردین 1391, 19:18 عصر
میتونی ()notify رو reimplement کنی و استثنائات رو در اونجا catch کنی

class CApplication : public QApplication
{
public:
CApplication(int &argc, char **argv) :
QApplication(argc, argv)
{ }

bool notify(QObject *receiver, QEvent *eve)
{
try {
return QApplication::notify(receiver, eve);
} catch (std::exception &e) {
//...
} catch (...) {
//...
}
}

};


int main(int argc, char *argv[])
{
CApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}



void Widget::on_pushButton_clicked()
{
int i;
throw i;
}

returnx
پنج شنبه 10 فروردین 1391, 21:17 عصر
والا من که چیزی به ذهنم نمیرسه.
اگه یه مثال از همچین حالتی بدین شاید بتونم جوابی بدم.
خوب در برنامه های بزرگ ، نمیشه تمام خطا ها رو پیش بینی کرد و فکر می کنم یک چیز عادی باشه...
مثلا ساده ترین حالت اینکه شما می خوای در یک فایل اطلاعاتی بنویسید ولی بطور کاملا اتفاقی این فایل توسط یک برنامه دیگه قبل از اینکه برنامه شما این فایل رو باز کنه باز شده...
بدیهی که سیستم عامل اجازه باز کردن این فایل رو به شما نمیده و یک خطا پیش میاد ، در بهترین حالت اینکه ما فقط خطای وجود نداشتن فایل مربوط رو در زمان کدنویسی پیش بینی می کنیم ، اما با مدیریت خطای اثتسنائات یک حالت کلی را تصور می کنیم که برنامه توانایی باز کردن این فایل رو نداره و بطور مثال به کاربر پیام Can't Open File رو میدیم ،اصولا در زبان های مختلف ابزاری برای مدیریت چنین خطا هایی وجود داره مثلا در C# از همین بلاک Try،Catch,Finaly رو داریم و یاد در VB شی Err برای مدیریت کامل خطا ها یا دستور On error Resum Next و در Vb.net هر دو شکل...

خیر، موردی که فرمودید فقط در محیط‌های مدیریت شده مانند دات‌نت و جاوا وجود دارد
حرف شما درست اما فکر نکنم این حرف مطلقا درست باشه ،چون Vb6 یک زبان native بود ولی چنین ابزاری توش پیش بینی شده بود

حامد مصافی
پنج شنبه 10 فروردین 1391, 21:43 عصر
حرف شما درست اما فکر نکنم این حرف مطلقا درست باشه ،چون Vb6 یک زبان native بود ولی چنین ابزاری توش پیش بینی شده بود
گمان می‌کنم یا بنده یا جهابعالی متوجه سوال دوستمون نشدیم. مطلقاً چنین چیزی در VB نداشتیم!


میتونی ()notify رو reimplement کنی و استثنائات رو در اونجا catch کنی
بدین ترتیب شما فقط خطا‌های احتمالی تابع QApplication::notify را مدیریت می‌کنید که این تابع هرگز خطایی تولید نخواهد کرد!



بدیهی که سیستم عامل اجازه باز کردن این فایل رو به شما نمیده و یک خطا پیش میاد ، در بهترین حالت اینکه ما فقط خطای وجود نداشتن فایل مربوط رو در زمان کدنویسی پیش بینی می کنیم ، اما با مدیریت خطای اثتسنائات یک حالت کلی را تصور می کنیم که برنامه توانایی باز کردن این فایل رو نداره و بطور مثال به کاربر پیام Can't Open File رو میدیم ،اصولا در زبان های مختلف ابزاری برای مدیریت چنین خطا هایی وجود داره مثلا در C#‎ از همین بلاک Try،Catch,Finaly رو داریم و یاد در VB شی Err برای مدیریت کامل خطا ها یا دستور On error Resum Next و در Vb.net هر دو شکل...
شما می‌خواهید فایلی را باز کنید. اط سیستم‌عامل تقاضای این‌کار را می‌کنید. دو حالت وجود دارد


این کار انجام می‌پذیرد و سیستم‌عامل یک اشاره‌گر به محلی از حافظه که می‌توانید با آن مراوده اطلاعاتی داشته باشید را به شما می‌دهد(یک اشاره‌گر)
این کار بنا به دلائلی ممکن نیست و سیستم‌عامل یک صفر بر‌می‌گرداند

این روند به خودی خود شامل هیچ خطایی نیست در برخی کتابخانه‌ها یا زبان‌ها لفاف دسترسی این خطا را تولید می‌کند. در زبانی مانند دات‌نت به چنین چیزی یک استثنا (نه خطا) گفته می‌شود و سی‌پلاس‌پلاس چون سطح پایین است و به خودی خود دربرگیرنده چنین لفاف‌ها یا مکانیزم‌هایی نیست و به همین منوال عمل می‌کند. که در پست دوم و توسط جناب mousamk (http://barnamenevis.org/member.php?14195-mousamk) بدان اشاره شده‌ است.


خطاهایی که باید مدیریت شوند به دسته سیستمی و کاربر گروه‌بندی می‌شوند خطاهایی سیستمی بسیار اندک هستند (مانند تبدیل اشتباه، تقسیم بر صفر، overflow و ...) که قابل پیش‌بینی هستند در مورد خطا‌های کاربر هم که با کلمه کلیدی throw انگیخته می‌شوند مطالعه مستندات کتابخانه مورد استفاده یا هماهنگی بین کد‌هایی که خودتان نوشته‌اید مسئله را حل می‌کند.

returnx
پنج شنبه 10 فروردین 1391, 23:01 عصر
ممنون در مورد جوابتون...
اما ،

گمان می‌کنم یا بنده یا جهابعالی متوجه سوال دوستمون نشدیم. مطلقاً چنین چیزی در VB نداشتیم!

نه،مخاطب من شما بودید ، یعنی پست #6 که شما جواب بنده رو دادید، شما در جواب من گفتید:

خیر، موردی که فرمودید فقط در محیط‌های مدیریت شده مانند دات‌نت و جاوا وجود دارد
منم هم گفتم :

حرف شما درست اما فکر نکنم این حرف مطلقا درست باشه ،چون Vb6 یک زبان native بود ولی چنین ابزاری توش پیش بینی شده بود
حالا نمیدونم ایا تصور من اشتباه هست!؟

حامد مصافی
پنج شنبه 10 فروردین 1391, 23:42 عصر
حالا نمیدونم ایا تصور من اشتباه هست!؟
این دوست عزیز اینطور فرموده بودند.

اما در برنامه ها بعضا خطاهایی ممکنه اتفاق بیفته که قابل پیشبینی نیست...
من برداشتم این بود که منظور ایشون این بود که روالی برای به دام انداختن کل خطا‌های برنامه وجود داشته باشد که در جواب به عرض رساندم چنین چیزی وجود ندارد. در برنامه نویسی بومی خطا‌ها فقط توسط برنامه‌نویس قابل کنترل هستند (برای مثال: بلوک try در c++) و چنین حالتی که بدون این بلوک کل خطا‌های برنامه توسط یک کلاس به دام بیفتند وجود ندارد