ورود

View Full Version : چگونگی بروز شدن اطلاعات در QTableView؟



armintirand
چهارشنبه 25 بهمن 1391, 12:17 عصر
سلام
من یک برنامه نوشتم که چنتا تب داره توی یکی از اونا یک QTableView دارم که با مادل به دیتابیس وصله وقتی برنامه رو اجرا میکنم از دیتابیس اطلاعاتو میخونه ولی وقتی توی قسمتهای دیگه برنامه دیتابیس رو تغییر میدم و برمیگردم به اون تب تا تغییرات رو مشاهده کنم نتیجه رو نشون نمیده و باید برنامه رو ببندم و دوباره باز کنم تا بروز بشه و البته توی همون تب هایی که به دیتابیس تغییراتی اعمال می‌کنم هم مادل‌های دیگه ای دارم که اونا هم بروز نمیشن.
آیا برای کار با مادل ها باید کار خاصی کنم تا خودشونو بروز کنن؟
ممنون

armintirand
پنج شنبه 26 بهمن 1391, 11:11 صبح
این یکی از کلاس‌های منه که باید اطلاعات از دیتابیس به صورت مدام توی اون بروز بشه یعنی هر تغییری ایجاد شد نشون بده
ListTab::ListTab(QWidget *parent)
{
QVBoxLayout *Vbox = new QVBoxLayout(this);
TableView = new QTableView();
QSqlQueryModel *m = new QSqlQueryModel();
m->setQuery("select * from mytable order by number");
TableView->setModel(m);
QLabel *lbl5 = new QLabel(trUtf8("موجودی انبار"));
Vbox->addWidget(lbl5);
Vbox->addWidget(TableView);
}

اگه کار خاصی باید انجام بدم تا خودشو بروز کنه لطفا بگین؟
ممنون

armintirand
پنج شنبه 26 بهمن 1391, 12:29 عصر
توی یکی از مقاله هایی که میخوندم این کد رو پیشنهاد داده بود ولی با این کد هیچ چیزی رو حتی اول باز کردن هم از دیتابیس نمیخونه
QVBoxLayout *Vbox = new QVBoxLayout(this);
TableView = new QTableView();
QSqlTableModel tblmodel;
tblmodel.setTable("mytable");
tblmodel.select();
TableView->setModel(&tblmodel);
QLabel *lbl5 = new QLabel(trUtf8("موجودی انبار"));
Vbox->addWidget(lbl5);
Vbox->addWidget(TableView);
این کد ها رو توی تابع قبلی گذاشتم ولی کلا چیزی نشون نداد

حامد مصافی
پنج شنبه 26 بهمن 1391, 12:40 عصر
به پایگاه‌داده متصل شده‌اید؟
خروجی Application Output چیزی در بر نداره؟

armintirand
پنج شنبه 26 بهمن 1391, 14:25 عصر
آقای مصافی این همون برنامه ای است که توی یک تاپیک دیگه در مورد مشکل کار کردنش توی ویندوز ازتون کمک خواستم و گفتم که توی لینوکس درست کار میکنه ولی توی ویندوز نه!
حالا توی لینوکس میخام مادل ها رو بروز کنه که بعد توی ویندوز هم مشکلش حل شد کامل باشه.
آره به پایگاه داده متصلم و ازش تو قسمتهای دیگه برنامه داده میخونم یا مینویسم ولی با کد اولی که بالا نوشتم فقط دفعه اول مادل کار میکنه و هربار بخوام اطلاعات بروز بشه باید برنامه رو ببندم دوباره باز کنم تا اطلاعات جدید بیاد و با کد دوم هم که کلا هیچ چیزی نشون نمیده.

armintirand
پنج شنبه 26 بهمن 1391, 15:01 عصر
کمی کدمو تغییر دادم به این صورت شد
QVBoxLayout *Vbox = new QVBoxLayout(this);
TableView = new QTableView();
//db2 = new QSqlDatabase();
QSqlTableModel *tblmodel = new QSqlTableModel(this,db2);
tblmodel->setTable("mytable");
tblmodel->select();
TableView->setModel(tblmodel);
QLabel *lbl5 = new QLabel(trUtf8("موجودی انبار"));
Vbox->addWidget(lbl5);
Vbox->addWidget(TableView);
که الان از دیتابیس داده میخونه ولی مثل دفعه اول بروز نمیشه

armintirand
پنج شنبه 26 بهمن 1391, 15:02 عصر
به پایگاه‌داده متصل شده‌اید؟
خروجی Application Output چیزی در بر نداره؟
الان این خروجی رو میده
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.

بعد اومدم تمام query هایی که بود بعد از اتمام کارشون با دستور query.clear(); غیر فعال کردم دیگه این پیغام رو نداد اما بازم بروز نمیکنه

armintirand
پنج شنبه 26 بهمن 1391, 21:39 عصر
خوب طاهرا ربطی به هیچ کدوم از دستورات بالا نداره و مشکل من باید جای دیگه ای باشه چون اونجور که من فهمیدم دوتا دستور بالا فقط در ایجاد جدول فقط خواندنی و قابل نوشتنی فرق دارن.
دوستان به این سوالم کم لطفی نکنین!

حامد مصافی
پنج شنبه 26 بهمن 1391, 23:56 عصر
نمیدونم چرا قبلاً سوالتو کامل نخونده بودم.
Model/View در کیوت یک مکانیزم آفلاین است. شما برای اینکه به نتیجه دلخواهتون برسید Model رو در کل برنامه یکی در نظر بگیرید و در قسمت‌های مختلف فقط از View های مختلف استفاده کنید.

armintirand
جمعه 27 بهمن 1391, 00:20 صبح
آقای مصافی میشه یکم بیشتر توضیح بدین.اگه ممکنه یک مثال بزنین شاید بهتر متجه بشم.
ببینین من۴ تا کلاس برای تب هام استفاده کردم که توی هر کدوم ویدگتی دارم که باید خودشو با دیتابیس بروز کنه حالا چه مادلی بسازم و توی کدوم کلاس بسازم و این ویدگت هام از چه نوعی باشن و از همه بدتر اینکه من این پروژه رو باید شنبه تحویل بدم .اگه ممکنه در مورد این موارد برام کمک کنین چون با این اوضاع کارایی که تا الان انجام دادم کشک بوده!
فقط خواهشا لینک ندین این چند روزه اونقدر توی سایتهای خارجی دنبال مطلب بودم که هر چی لینک بدین تکراری میشه.
ممنون

armintirand
جمعه 27 بهمن 1391, 19:01 عصر
راستی یک مطلب الان به ذهنم رسید:
من چه ۱ مادل یا ۶۰ تا مدل یا یک View یا ۶۰ تا بخوام توی برنامه ام باشه مشکلم اینه که میخام هر مادل به دیتابیس به صورت مداوم وصل باشه و View هم خودشو هر لحظه از مادل خودشو بروز کنه.مشکل اینه که هر کدوم اینا خودشونو بروز نمیکنه و مساله اینه که من برای تغییر دیتابیس از مادل استفاده نکردم و با یک دستور insert ساده یا update استفاده کردم ولی چون میخام به صورت دائمی تغییراتو ببینم میخام از مادل برای مشاهده نتیجه تغییرات استفاده کنم.اصلا فرض کنید من دیتابیس رو بیرون از برنامه با کنسول پایگاه داده تغییر دادم و میخام توی برنامه بلافاصله نتیجه بروز بشه.
(البته تغییرات توی برنامه قراره اعمال بشه اینو به عنوان مثال گفتم)
ممنون

armintirand
دوشنبه 30 بهمن 1391, 21:12 عصر
خب این چند روز کمی از مادل سر در آوردم اولا این چیزی که میخاستم مثلا بیرون از برنامه دیتابیس تغییر کنه و نتیجه اون توی برنامه بلافاصله مشخص باشه به این راحتی نیست ولی حالا اون چیزی که بدرد من میخوره اینه:
من باید یک مادل تعریف بکنم و توی تمام کلاسهام اونو به View وصل بکنم اما مشکل اینجاست که من روش این کار رو نمیدونم.آیا باید یک کلاس تعرف کنم و اونو با کلاسهای View دوست بکنم یا روش دیگه و اینکه چجوری من مادل موجود توی یک کلاس دیگه رو از کلاس دیگه ای درون اسلاتهای اون کلاس بروز کنم.خودم میدونم کل نوشته هام چه مفهومی داره ولی فکر میکنم خیلی گنگ نوشتم ولی با توجه به پست های قبلیم تقریبا معلومه که چه کاری میخام انجام بدم.
ممنون

حامد مصافی
دوشنبه 30 بهمن 1391, 23:40 عصر
به کد خودتون توجه کنید:

QVBoxLayout *Vbox = new QVBoxLayout(this);
TableView = new QTableView();
//db2 = new QSqlDatabase();
QSqlTableModel *tblmodel = new QSqlTableModel(this,db2);
tblmodel->setTable("mytable");
tblmodel->select();
TableView->setModel(tblmodel);
QLabel *lbl5 = new QLabel(trUtf8("موجودی انبار"));
Vbox->addWidget(lbl5);
Vbox->addWidget(TableView);

اینجا یک مدل با نام tblmodel تعریف شده. و یک ویو با نام TableView

وظیفه مدل نگهداری اطلاعات و وظیفه ویو نمایش اونهاست. اگر ویو تغییری در داده‌ها ایجاد کنه مدل رو از این تغییر آگاه می‌کنه و در صورت پذیرش این تائید مدل اون‌رو به تمام ویو‌های متصل به خودش اعلام می‌کنه. در واقع مدل یک گره آفلاین در اتصال به منبع‌داده‌هاست. در این مثال شما مدل اطلاعات دریافتی رو از پایگاه داده دریافت می‌کنه و اون رو در خودش نگه میداره. تعریف بیش از یک مدل یک خطای محرز برنامه‌نویسی است. چون:

هر مدل اطلاعات رو جداگانه کش می‌کنه و مصرف رم بالا میره.
هر مدل تغییر اطلاعات رو به صورت جداگانه به منبع‌داده‌ها ارسال میکنه و سایر مدل‌ها از این تغییر آگاه نمیشن.
هر ویو برای به‌روزآوری نمایش اطلاعات نیازمند اینه که مدل مربوطه مجددا اطلاعات رو دریافت کنه


حالا چاره کار:

//init database here
QSqlTableModel *tblmodel = new QSqlTableModel(this,db2);
tblmodel->setTable("mytable");
tblmodel->select();

QTableView TableView1 = new QTableView(this);
TableView1->setModel(tblmodel);
TableView1->show();

QTableView TableView2 = new QTableView(this);
TableView2->setModel(tblmodel);
TableView2->show();

QTableView TableView3 = new QTableView(this);
TableView3->setModel(tblmodel);
TableView3->show();

همونطوری که میبینی یک مدل به همراه چندین ویو مرتبط با اون تعریف شدند. اطلاعات در سه ویو در مدل مربوطه (tblmodel) نگهداری میشه و این به این معنیه که این ویو ها از تغییرات همدیگه به صورت آنی باخبر میشن. حالا تو به توجه به سناریوی برنامت می‌تونی این شبه کد رو گسترش بدی. هر ویو رو در یک کلاس دیگه تعریف کن و اشاره‌گر مدل رو به اون کلاس پاس بده تا در متد setModel استفاده بشه.

armintirand
سه شنبه 01 اسفند 1391, 09:39 صبح
اون قسمت کدهایی که نوشتین رو میدونستم ولی نیاز به چیزی که در ۲ خط آخر نوشتین داشتم البته مشکل به کیوت دیگه مربوط نمیشه این دیگه پیاده سازی C++ است .با توجه به فرموده شما آیا من اشاره گر مادل را به عنوان پارامتر به سازنده کلاسی که ویو در آن تعریف شده باید بفرستم؟ و توی اون از آدرس اون مادل استفاده کنم؟
ممنون

aidinMC
دوشنبه 07 اسفند 1391, 00:10 صبح
اون قسمت کدهایی که نوشتین رو میدونستم ولی نیاز به چیزی که در ۲ خط آخر نوشتین داشتم البته مشکل به کیوت دیگه مربوط نمیشه این دیگه پیاده سازی C++ است .با توجه به فرموده شما آیا من اشاره گر مادل را به عنوان پارامتر به سازنده کلاسی که ویو در آن تعریف شده باید بفرستم؟ و توی اون از آدرس اون مادل استفاده کنم؟
ممنون
من سه چهارتا پست آخری رو خوندم، ولی بله شما باید آدرس مدل رو به کلاس ویو بفرستی...
مثلا یه همچین حالتی سازنده تعریف کن

TEST::TEST(&MODEL){
__MODEL = MODEL; // __MODEL tu ghesmat private bayad tarif beshe....

armintirand
دوشنبه 07 اسفند 1391, 00:18 صبح
اگه یک کلاس داشته باشم که مادلم توی اون تعریف بشه و یک کلاس که ویو در اون تعریف شده من که نمیتونم توی سازنده کلاس ویو یا هر قسمت دیگه اون به مادلی که در کلاس دیگه تعریف شده دسترسی داشته و اونو بروز کنم مگر اینکه این کلاس ویو دوست کلاس مادل باشه درسته؟

aidinMC
دوشنبه 07 اسفند 1391, 00:20 صبح
خودت جوابو گفتی دیگه ، بله درسته...

armintirand
دوشنبه 07 اسفند 1391, 00:24 صبح
نه اینکه C++ رو ترکوندم (هربار کتابی یا مطلبی از C++ میخونم میبینم این اساتیدی که به ما برنامه نویسی یاد داده بودن چقدر حقمون رو خوردن:متفکر:)از نوشتن کد ترس دارم باهاش کمی ور میرم به هر جا رسوندم فردا باهاتون هماهنگ میکنم.
ممنون