ورود

View Full Version : مشکل با اتصال بیشتر از یک در sqlite



armintirand
جمعه 06 بهمن 1391, 19:19 عصر
سلام
من تازه موفق شدم در کیوت با پایگاه داه کارکنم و یچیزایی هم نوشتم ولی از اونحایی که sqlite تک کاربره است(اگه ممکنه همین تک کاربره بودن رو کمی توضیح بدین؟) در برنامه من که از چند تا تب تشکیل شده و هر کدوم یک کلاس مشتق شده از QMainWindow هستن و همه تب ها نیاز دارن با پایگاه داده در ارتباط باشن تعداد اتصال های من بیش از یکی است و وقتی با برنامه کار میکنم تو محیط خود کیوت هشدار میده که اتصال قدیمی رو پاک کردم و اتصال جدید رو جایگزین اون کردم و این در یکی از تب ها که از مادل استفاده کردم و توی اون گزارش میگیرم باعث میشه که اطلاعات بروز نشه و آخرین گزارشو نمیده!
حالا راه حل چیه که بتونم اصالات هر کلاسمو حفظ کنم.
۲تا مشکل کوچیک دیگه هم داشتم نخواستم تاپیک دیگه بزنم گفتم همینجا بپرسم
توی یکی از کلاسها یک ComboBox دارم که هر مقدارش تغییر بکنه میریزم توی یک QTableWidget و ComboBox رو قابل ویرایش کردم تا بتونم علاوه برمقادیر پیشفرض مقادیر جدیدی هم وارد کنم اما وقتی مقدار جدیدی وارد میکنم و اینتر میزنم سطر جدید توی جدول ایجاد میشه ولی مقدار جدید ارصال نمیشه!و جدولم خالی میشه اگه لازمه کدی که نوشتمو هم بذارم.
مورد آخر هم مرتب کردن اظلاعات درون مادلم هست این مادل اطلاعات رو از دیتابیس میگیره و من میخام براش قابلیت اینو بزارم که برحسب صعودی یا نزولی بودن یکی از ستونها مرتب بشه و چون مادله این قابلیت برای گزارش گرفتن امکانات جالبی ایجاد میکنه.
ممنون

حامد مصافی
جمعه 06 بهمن 1391, 19:29 عصر
QSqlDatabase::adDatabase رو فقط یک بار فراخوانی کنید


... اگه لازمه کدی که نوشتمو هم بذارم.
بله لازمه!

از qSort استفاده کن

و نکته دیگر اینکه هر سوال رو در یک تاپیک بپرس

armintirand
جمعه 06 بهمن 1391, 19:48 عصر
همه چی بکنار قانونای اینجا بکنار:بامزه:
من بدون مشکل تعداد اتصالهارو به یک کاهش دادم ولی همچنان اون پیغام هشدار پابرجاشت و مادل بروز نمیشه
در ضمن کدم خیلی شلوغ و زیاده نمیخام زحمت مطالعه برنامه نویسی بدم رو بهتون بدم.
در مورد راهنمایی در مورد مرتب کردنتون هم تست میکنم و نتیجه رو میگم.
ممنون

returnx
جمعه 06 بهمن 1391, 22:41 عصر
من با دیتابیس در Qt هنوز کار نکردم(هنوز شاسش پیدا نکردم)!! ولی اینکه شما می خواین تعداد اتصال ها به بانک کم شه و فقط یک اتصال وجود داشته باشه ، بدون شک بهترین راه استفاده از معماری چند لایه است ، به این دلیل که در این روش فقط لایه DataAccess هست که به Data base وصل میشه ، و شما Query ها رو توسط لایه های بالا تر به این لایه می فرستید و نتیجشو میبینید...

alamate_aoal
دوشنبه 09 بهمن 1391, 07:40 صبح
سلام

تک کاربره در ساده ترین تعریف یعنی اگر برنامه A در حال کار با پایگاه داده x هست برنامه B نمیتونه ازش استفاده کنه(در حقیقت x قفل شده).
پارامتر دوم از متد addDatabase نام کانکشن میگیره.اگه قصد ایجاد چندین کانکشن داری این پارامتر رو با مقادیر مختلف در هر بار فراخوانی addDatabase مقدار دهی کن

armintirand
جمعه 13 بهمن 1391, 01:41 صبح
ببینید من یک combobox دارم که با دستور زیر اسلات مورد نطر رو فراخانی کردم
connect(Combo,SIGNAL(currentIndexChanged(QString)) ,this,SLOT(on_btnAddToList_clicked()));
و combobox ور به صورت editable قرار دادم حالا که داده جدید وارد این combo میکنم اونو به جدول اضافه نمیکنه
اینم تابع اسلات
void GetTab::on_btnAddToList_clicked()
{
int row = Table->rowCount();
qDebug() << "rows = " << row;
Table->setRowCount( row+1 );
QTableWidgetItem *item = new QTableWidgetItem ;
item->setText(Combo->currentText());
Table->setItem(row , 0 , item);
}
البته اگه از داده های خود combobox استفاده کنم اونارو به جدول اضافه میکنه ولی جدیدارو قبول نمیکنه.به نظرتون مشکل کجاست؟
در ضمن من هنوز مشکل ارتباط sqlite رو نتونستم حل کنم الان فقط یک بار تابع connection رو فراخانی کردم ولی نمیدونم چرا همون اول هشدار میده و در ضمن QTableview خودشو بروز نمیکنه.

armintirand
جمعه 13 بهمن 1391, 16:18 عصر
دوستان سوال منو بی پاسخ نذارین
پروژه خوابیده شرمنده

armintirand
شنبه 14 بهمن 1391, 00:41 صبح
با دستور زیر
connect(Combo,SIGNAL(editTextChanged (QString)),this,SLOT(on_btnAddToList_clicked()));
اگر چیزی تایپ کنم برای هر حرفی که تایپ میکنم یکبار اسلاتم فراخانی مبشه
قبال برای یک QLineEdite با این اسلات کار کرده بودم ولی اونجا از سیگنال editingFinished نیز کمک گرفتم تا بدونم چوقت قراره اون عبارت تایپ شده رو توی جدول قرار یدم ولی متاسفانه QComboBox اسلاتی مشابه editingFinished نداره.حالا چیکار کنم؟

alamate_aoal
شنبه 14 بهمن 1391, 10:59 صبح
قبلا اینجا (http://barnamenevis.org/showthread.php?364995-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%D8%A7%D8%B1%D8%AA%D8%A8%D8%A7%D8%B7-%D8%A8%DB%8C%D9%86-QComboBox-%D9%88-QLsiBox-%D8%9F&p=1617083#post1617083)یک مثال مرتبط با این سوال شما آپلود کرده بودم(آنجا هم خودتون سوال رو پرسیده بودید). در این ضمیمه کدهای زیر را به همان مثال اضافه کردم :
class ComboBox : public QComboBox
{
Q_OBJECT

public:
ComboBox(QWidget *parent=0): QComboBox(parent)
{
this->setLineEdit( m_lineEdit = new QLineEdit );
connect( m_lineEdit, SIGNAL(editingFinished()),
SIGNAL(editingFinished())) ;
}
~ComboBox(){ delete m_lineEdit; }

signals:
void editingFinished();

private:
QLineEdit *m_lineEdit;

};


MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
...
connect( ui->comboBoxItems, SIGNAL(editingFinished()),
SLOT(on_btnAddToList_clicked()) );
...
}

و کلام آخر اینکه توصیه می کنم تا حد ممکن بجای استفاده از editingFinished از یک pushbutton برای تایید ورود کاربر استفاده کنید99412

armintirand
یک شنبه 15 بهمن 1391, 00:43 صبح
در ظاهر مشکلمو حل کردم ولی این حل شدن همانا و نمیدون به چه علت داغون شدن قسمتای دیگه همانا
الان از QComboBox میتونم داده به توی جدولم بفرستم برای اینکار با
connect(Combo,SIGNAL(editTextChanged (QString)),this,SLOT(set_ComboEdit2(QString)));
مقادیر تایپ شده رو به وسیله اسلات مورد نظر درون یک متغیر میریزم و در آخرین ستون اون ردیف با
connect(LnEdit3,SIGNAL(editingFinished()),this,SLO T(set_ComboEdit2Table()));
آخرین نقدار متغییر رو به جدول اضافه میکنم ولی جالب اینه که الان وقتی میخام به ستونای دیگه داده اضافه کنم یک ردیف قبل اضافه میکنن یعنی برای ردیف اول اضافه نمیکنن و در ردیف دوم میان به ردف اول اضافه میکنن ولی ستون اولم که از Combobox گرفته میشه درسته
دیگه واقعا هنگ کردم:گیج:
اگه این همه وقتمو برای نوشتن سیستم عامل میذاشتم الان :متفکر:
ممنون میشم کمکم کنید

armintirand
یک شنبه 15 بهمن 1391, 16:49 عصر
جالب تر ازهمه اینه که الان پروژه رو بردم توی ویندوز با کیوت کامپایل کردم بعد تمام dll های مورد نیازشو کنارش گذاشتم توی ویندوز۷ اجرا میشه ولی وقتی دیتابیس ایجاد میکنه با دیتابیس نمیتونه ارتباط برقرار کنه و دفعه دوم که اجرا کنم اگه فایل دیتابیس کنارش باشه ارور میده میگه برنامه به دلیلی باید بسته بشه و توی ویندوز xp هم که همون اول ارور dont send میده ولی توی لینوکس این مشکلو نداشت.الان دارم دنبال یک دیوار محکم میگردم سرمو بکوبم بهش :عصبانی++:پیشنهاد خاصی برای دیوار محکم ندارین؟

armintirand
دوشنبه 16 بهمن 1391, 10:36 صبح
قبلا اینجا (http://barnamenevis.org/showthread.php?364995-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%D8%A7%D8%B1%D8%AA%D8%A8%D8%A7%D8%B7-%D8%A8%DB%8C%D9%86-QComboBox-%D9%88-QLsiBox-%D8%9F&p=1617083#post1617083)یک مثال مرتبط با این سوال شما آپلود کرده بودم(آنجا هم خودتون سوال رو پرسیده بودید). در این ضمیمه کدهای زیر را به همان مثال اضافه کردم :
class ComboBox : public QComboBox
{
Q_OBJECT

public:
ComboBox(QWidget *parent=0): QComboBox(parent)
{
this->setLineEdit( m_lineEdit = new QLineEdit );
connect( m_lineEdit, SIGNAL(editingFinished()),
SIGNAL(editingFinished())) ;
}
~ComboBox(){ delete m_lineEdit; }

signals:
void editingFinished();

private:
QLineEdit *m_lineEdit;

};


MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
...
connect( ui->comboBoxItems, SIGNAL(editingFinished()),
SLOT(on_btnAddToList_clicked()) );
...
}

و کلام آخر اینکه توصیه می کنم تا حد ممکن بجای استفاده از editingFinished از یک pushbutton برای تایید ورود کاربر استفاده کنید99412
الان مثال آماده ای که فرستاده بودین رو تست کردم اگه نگاه کنین مال شما اوضاش خیلی خرابتره البته جسارت نباشه شما استاد ما هستین براتون پیغام خصوصی دادم اگه ممکنه پیگیریش کنین
ممنون

alamate_aoal
دوشنبه 16 بهمن 1391, 18:49 عصر
این کدها رو تست کن:

class ComboBox : public QComboBox
{
Q_OBJECT

public:
ComboBox(QWidget *parent=0): QComboBox(parent) { }

protected:
void focusOutEvent(QFocusEvent *e)
{
QWidget *activePopupWidget, *parent, *parentOfParent ;
activePopupWidget = parent = parentOfParent = 0;

activePopupWidget = qApp->activePopupWidget();

if (activePopupWidget)
{
parent = activePopupWidget->parentWidget();
if (parent)
parentOfParent = parent->parentWidget();
}

bool popupIsChild = false;
if (parent == this || parentOfParent == this)
popupIsChild = true;

if (e->reason() != Qt::PopupFocusReason && !popupIsChild)
emit editingFinished();

QComboBox::focusOutEvent(e);
}

void keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter)
emit editingFinished();
QComboBox::keyPressEvent(e);
}

signals:
void editingFinished();
};

armintirand
سه شنبه 17 بهمن 1391, 09:44 صبح
جالب تر ازهمه اینه که الان پروژه رو بردم توی ویندوز با کیوت کامپایل کردم بعد تمام dll های مورد نیازشو کنارش گذاشتم توی ویندوز۷ اجرا میشه ولی وقتی دیتابیس ایجاد میکنه با دیتابیس نمیتونه ارتباط برقرار کنه و دفعه دوم که اجرا کنم اگه فایل دیتابیس کنارش باشه ارور میده میگه برنامه به دلیلی باید بسته بشه و توی ویندوز xp هم که همون اول ارور dont send میده ولی توی لینوکس این مشکلو نداشت.الان دارم دنبال یک دیوار محکم میگردم سرمو بکوبم بهش :عصبانی++:پیشنهاد خاصی برای دیوار محکم ندارین؟
کسی نظری درباره این مشکل نداره؟

alamate_aoal
سه شنبه 17 بهمن 1391, 10:33 صبح
پوشه‌ی sqldrivers رو از مسیری شبیه مسیر زیر کنار برنامه‌ تون کپی کردید؟(فقط پلاگین های مورد نیاز)
c:\Qt\MSVC2010-4.8.4\plugins\sqldrivers

برنامه رو از طریق کامند پرامپت اجرا کن تا بتونی خطاها رو در کنسول مشاهده کنی
ایضا" متن خطا رو قید بفرمایید

armintirand
جمعه 20 بهمن 1391, 01:54 صبح
نه ابتدا با sdk کامپایل کردم بعد با کلیک روی فایلم ارور هایی برای فایلهای dll داد و هر کدومو جست و جو کردم و جالب اینه که برای هر کدوم ۲ تا فایل دقیقا هم حجم می یافت و فقط اونا رو کنار فایل اجراییم گذاشتم که این اتفاقا میفته
حالا با فرمایش شما من باید این پوشه drivers رو از مسیری که گفتین به صورت کامل کنار فایل اجراییم بذارم؟
با ویندوز در کنسول هم تست میکنم و خطاهاشو میذارم.

alamate_aoal
جمعه 20 بهمن 1391, 19:14 عصر
متناسب با ماژول‌هایی که در برنامه‌تون استعمال کردید, فایل های dll مربوطه را از پوشه‌ی bin از محل نصب کیوت به کنار فایل اجرایی کپی کن. همچنین برای انتشار, برنامه را در حالت release کامپایل کن


حالا با فرمایش شما من باید این پوشه drivers رو از مسیری که گفتین به صورت کامل کنار فایل اجراییم بذارم؟
در پست قبلی عرض کرده بودم: "فقط پلاگین های مورد نیاز". احتمال میدم برای شما qsqlite4.dll و پوشه‌ی imageformats باشه

برای توضیحات تکمیلی حتما عبارت Deploying an Application on Windows را در Assistant جستجو کن

armintirand
سه شنبه 24 بهمن 1391, 16:23 عصر
اون فایل dll و اون دوشه رو کنار فایل اجرایی گذاشتم بازم ارور داد
حالا فقط مونده که با کنسول اجرا کنم ببینم چه اروری میده و اون عبارتو که گفتین توی help کیوت بخونم
اگه شما هم چیزی به دهنتون میرسه که از قلم افتاده بگین شاید این مشکلمم حل بشه.
ممنون

حامد مصافی
سه شنبه 24 بهمن 1391, 16:34 عصر
کنار برنامه یک فولدر با نام plugins بساز، داخل این فولدر یک فولدر با نام sqldrivers بساز و اون dll رو بنداز داخل این فولدر

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

حامد مصافی
پنج شنبه 26 بهمن 1391, 11:10 صبح
کد اون قسمتی رو که برای اتصال به دیتا‌بیس نوشتی رو میشه ببینم؟

armintirand
پنج شنبه 26 بهمن 1391, 12:13 عصر
{
db1 = QSqlDatabase::addDatabase("QSQLITE");
db1.setHostName("localhost");
db1.setDatabaseName(dbName);

bool isDbFileAlreadyExists = QFile::exists(dbName);
if (!isDbFileAlreadyExists) {
QSqlQuery query(db1);
query.exec("create table mytable (drugname varchar(20) not null,number int(5) not null default 0,price int(10) not null default 0)");
query.exec("create table bime (bimename varchar(20) not null,takhfif int(3)) not null default 0");
}
}

البته این کد کاملا توی لینوکس بدرستی کار میکنه وبه همین دلیل فکر نکنم مشکل از کد باشه فکر کنم توی dll ها مشکلی باشه
منتظر پاسختون هستم
ممنون

armintirand
پنج شنبه 26 بهمن 1391, 13:16 عصر
این یک تابع بود که اتصال رو ایجاد میکنه و کد زیریکی از مادل های منه که اونو فراخانی میکنه
if(createConnection())
{
m->setQuery("select drugname from mytable");
Combo = new QComboBox;
Combo->setModel(m);
// Combo->setCurrentIndex(2);
}
و تو بقیه برنامه از این اتصال پیش فرض استفاده میکنم.
کدم کمی نامرتب و شلوغه اگه میخاهید کل کدمو بزارم.
ممنون

حامد مصافی
پنج شنبه 26 بهمن 1391, 17:16 عصر
اگه روی لینوکس درسته و روی ویندوز مشکل داره Debugش کن ببین کجا خطا میده خب

armintirand
پنج شنبه 26 بهمن 1391, 19:39 عصر
دیباگ کردم این ارور رو داد من که ازش چیزی سر در نیاوردم
این کپی اون اروره

Signal received
---------------------------
<p>The inferior stopped because it received a signal from the Operating System.<p><table><tr><td>Signal name : </td><td>SIGSEGV</td></tr><tr><td>Signal meaning : </td><td>Segmentation fault</td></tr></table>
---------------------------
OK
---------------------------

حامد مصافی
پنج شنبه 26 بهمن 1391, 22:36 عصر
اینطوری جواب دادن سخته چون نمیدونیم کدوم قسمت برنامت ارور داره. قبل از اعمال کلیدی یک پیغام با qDebug چاپ کن و محل دقیق رخ دادن خطا رو کشف کن و کد همون قسمت رو اینجا بذار

armintirand
جمعه 27 بهمن 1391, 00:23 صبح
اصلا برنامه برای اجرا نمیره که چیزی با qDebug بخاد چاپ بشه در ضمن وقتی در لینوکس درست کار میکنه یعنی مشکل از کد من نیست مگه اینجوری نیست؟
بازم اگه لازمه من کل پروژه رو بفرستم نگاه کنین البته با کمال شرمندگی!:خجالت:

armintirand
جمعه 27 بهمن 1391, 13:38 عصر
الان شروع کردم به کامنت کردن قسمت‌خای مختلف برنامه و کامپایل.ابتدا تمام کلاسهامو کامنت کردم و اجرا شد و کم کم قسمت کامنت رو کمتر کردم و نمیدونم چی شد که یدفه درست شد البته یک کار دیگه هم کردم
encoding فایلهام توی لینوکس تعریف شده بود منظورم فایلهای سورس هست اونو اینجا یکبار utf8 کردم که کلا نوشته هام قاطی شد بعد برگردوندم به system و بعد تست کردم کلا درست شد:گیج:
این ویندوز همه جا باید خودشو نشون بده که بی دلیل یک چیزی یوقت کار کنه یکوقت نکنه میترسم تحویل بدم مشتری ببره روس سیستم خودش کار نکنه واقعا عجیبه!!!
حالا موند فقط مشکل بروز شدن مادل ها اگه ممکنه توی این تاپیک کمکم کنید
http://barnamenevis.org/showthread.php?383993-%DA%86%DA%AF%D9%88%D9%86%DA%AF%DB%8C-%D8%A8%D8%B1%D9%88%D8%B2-%D8%B4%D8%AF%D9%86-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA-%D8%AF%D8%B1-QTableView%D8%9F
ممنون