# Native Code > برنامه نویسی با C > برنامه نویسی در محیط QT و هم خانواده هایش >  ایجاد ارتباط بین QComboBox و QLsiBox ؟

## armintirand

سلام
من یک برنامه دارم که میخوام از یک کومبوباکس یک کلمه رو بگیرم و بعد از یک لاین ادیت عدد بگیرم بعد با یک ارتباط از طریق سیگنال و اسلات اونو توی یک ویدجت که هر کلمه و عدد رو توی یک ردیف قرار میده قرار بدم و بعد ردیف بعد رو با همون ورش قبل پر کنم مثلا فرض کنید برنامه یک کتابخونس که توی هر ردیف نام کتاب و کدش وارد میشه و بعد نیاز دارم اونارو توی دیتابیس ذخیره کنم بر ای این کاز من QListBox  رو مناسب دیدم وتابعی برای اسلاتش نوشتم ولی جوای نداد البته تابع کانکت کار میکنه ولی تابع اسلات کارنمیکنه.اگه میشه منو راهنمایی کنید تا بدونم اولا QListBox برای من انتخاب مناسبیه و چطور این ارتباطو بسازم.راستی برای دیتابیس از Sqlite میخوام استفاده کنم اگه ممکنه برای کار با اون توی کیوت والبته کمی هم در مورد دستورات خود Sqlite برام توضیح بدید ممنون میشم.
ممنون

----------


## rubiks.kde

اینا کلی مثال در مورد استفاده از sqlite توی کیوته
http://doc.qt.digia.com/4.5/examples.html#sql
http://stackoverflow.com/questions/6...tabase-in-qt-c

----------


## alamate_aoal

سلام
این مثال هم سیگنال/اسلات رو پوشش میده و هم مبحث پایگاه داده رو

----------


## armintirand

مثال شما خیلی کمکم کرد و من با دیتابیس Sqlite آشنا شدم ولی من سگنال و اسلات دیگه ای مد نظرمه.میخام اول از ComboBox موارد انتخاب شده رو دونه دونه به QListView بفرستم بعد از اضافه کردن چند ردیف همه رو یک جا از QListView توی دیتابیس ذخیره کنم. که همونطور که قبلا هم گفتم نمیدونم سیگنال و اسلات ارسال آیتم از ComboBox به QListView به چه صورته؟ و بعد این کار به داده های درون QListWiew چجور دسترسی داشته باشم تا بتونم توی دیتابیس بریزم.
ممنون

----------


## alamate_aoal

> نمیدونم سیگنال و اسلات ارسال آیتم از ComboBox به QListView به چه صورته؟


 listWidget->addItem( comboBox->currentText() );
تو خط بالا currentText و addItem هر دو متدند , ربطی به سیگنال و اسلات ندارن




> به داده های درون QListWiew چجور دسترسی داشته باشم تا بتونم توی دیتابیس بریزم



for ( int i=0; i<listWidget->count(); i++ )
       QMessageBox::information(this, "", listWidget->item(i)->text() );

----------


## armintirand

دوست عزیز شما توی برنامه‌ای که اینجا قرار دادین با QListView کارکردید و با مادل سروکارداشتین. و منم درباره اون سوال پرسیدم ولی شما در مورد افزودن ایتم از QComboBox به QListWidget در پست قبلی توضیح دادین که اگر اشتباه نکنم نمیتونه با مادل کارکنه لطفا به من در مورد افزودن آیتم از QComboBox به  QListView هم کمک کنید.البته این مورد توی هر دو کدی که بالا برام گذاشتین وجود داره لطفا برای هر دو مثال بزنید.
ممنون

----------


## armintirand

با برسی هایی که کردم متوجه شدم که برای برنامه من مادل به درد نمی‌خوره و باید از QTableWidget استفاده کنم ولی امان از نبود منابع!حالا مبخام از همون ComboBoxکه بالا گفتم و هنوز جوابی نگرفتم به این QTableWidget آیتم اضافه کنم و آخر هر وقت خواستم چند تا ردیف که شد توی دیتابیس ذخیره کنم . یعنی همون توضیحاتی که آقای علامت سوال باالا در مورد QListWidget فرمودن در مورد QTableWidget بگن مشکل من حل میشه.
ممنون

----------


## rubiks.kde

دقیقا نمیدونم چیکار میخواهید بکنید ؟

ولی اگه میخوایید با تغییر آیتم combobox آیتم جاری رو به tablewidget اضافه کنید با یه سلات خودتون بنویسید که آیتم رو بگیره بعد یه آیتم برای tablewidget بسازید و اون رو اضافه کنید مثل کد زیر :
void mainwindow::additem(QString item)
{
    int rc = tablewidget->rowCount() ;
    ui->tablewidget->setRowCount(rc + 1);
    QTableWidgetItem *item_1 = new QTableWidgetItem(item,1);
    ui->tablewidget->setItem(rc, 0, item_1);
}

اگه همین اسلات رو برای سیگنال currentIndexChanged مربوط به combobox بنویسی حله.

----------


## armintirand

تو این فایلی که گذاشتم از روش شما نتونستم Signalو slot رو به هم وصل کنم و در ضمن table هم نمیدونم چجور برای هر ستونش عنوانی بنویسم اگه ممکنه فایل منو ویرایش کنید تا از روی اون پروژه خودمو تکمیل کنم.
ممنون

----------


## alamate_aoal

توی این مثال بسته به پیکربندی فایل پروژه(pro.*) از QListWidget یا QTableWidget برای دریافت اطلاعات موجود در QComboBox و از QTableView برای نمایش محتویات بانک استفاده میشه.
با کلیک راست روی QListWidget یه کانتکست منو ظاهر میشه که با اون میتونی آیتم ها رو در لیست جابجا یا حذف کنی[اشانتیون :لبخند گشاده!: ].

برای استفاده از QTableWidget خط سوم از فایل پروژه رو Disable کن :
DEFINES += USE_QListWidget
و بعد از اون حتما یکبار پروژه را Clean کن (در صورت نیاز qmake رو هم Run کن)

----------


## armintirand

ممنون از مثالتون در حال مطالعه کدهاتون هستم لطفا نحوه قرار دادن هدر برای QTableWidget را نیز توضیح دهید.

----------


## rubiks.kde

توی فایل ui رو Table widget راست کلیک کنید و گزینه edit item رو بزنید در صفحه باز شده هدر ها رو به صورت سطری یا ستونی تعریف کنید

----------


## armintirand

دوست من اینقدرا هم iq من پایین نیست دیگه!من کلا دارم کد میزنم و از محیط گرافیکی کیوت استفاده نکردم و نیاز به کد مورد نظر برای این کار دارم. بازم ممنون از کمکاتون

----------


## rubiks.kde

سلام دوست عزیز این که جای ناراحتی نداره خوب میگفتی از محیط گرافیکی استفاده نمی کنی حالا بیا اینم یه مثال کوچیک از این کاری که میخوایی انجام بدی :

#include <QApplication>
#include <QMainWindow>
#include <QTableWidget>

int main(int argc, char **argv)
{
        QApplication app(argc, argv);

        QMainWindow *window = new QMainWindow();

        window->setWindowTitle(QString::fromUtf8("QTableWidget Set Header Title"));
        window->resize(400, 250);

        QTableWidget* table = new QTableWidget();

        //Set table row count 1 and column count 3
        table->setRowCount(1);
        table->setColumnCount(3);

        table->setSizePolicy(QSizePolicy::Expanding,QSizePolicy:  :Expanding);

        //Set Header Label Texts Here
        table->setHorizontalHeaderLabels(QString("HEADER 1;HEADER 2;HEADER 3").split(";"));

        //Add Table items here
        table->setItem(0,0,new QTableWidgetItem("ITEM 1"));
        table->setItem(0,1,new QTableWidgetItem("ITEM 2"));
        table->setItem(0,2,new QTableWidgetItem("ITEM 3"));

        window->setCentralWidget(table);
        window->show();
        return app.exec();
}

----------


## armintirand

ممنون از راهنماییهاتون کارم خیلی خوب جلو رفته و مهمتر از همه که احساس می‌کنم با کیوت خیلی راحت شدم.
فق یک سوال؟
شما توی اون فایلی که اتچ کرده بودین توی فایل mainwindow.cpp دستوری به این صورت بود 
    garbage.append(item);
که وقتی توی کدم میزارم میگه این garbage رو نمیشناسه جای دیگه هم که تعریفش نکردین البته من ندیدم. و یک مشکل دیگه شما هیچ تابع کانکتی برای ارتباط بین سیگنال و اسلات ComboBox و QTableWidget بکار نبردین پس چطور با هربار انتخاب یک مورد از ComboBox آیتم ها منتقل میشن؟(برام خیلی جالبه) البته جالبترش استفاده از ماکرویی هست که کد میتونه هم در حالت QTableView کامپایل بشه  و هم به حالت QTableWidget که این موردو متوجه شدم ولی اگه قبلیارو بگین مشکلم بکلی حل میشه.
ممنون

----------


## armintirand

من پروژمو تا اینجا جلو بردم ولی برای ارسال داده ها از ComboBox به TableWidget مشکل دارم پروژه رو اینجا قرار دادم اگه ممکنه کمکم کنید.

----------


## alamate_aoal

خواهش میکنم
نیازی به garbage نیست, میتونید ازش صرف نظر کنید
اگه از کیوت کریتور بعنوان محیط توسعه استفاده میکنی برای پیدا کرن تعریف یک سیمبل بعد از کلیک روی اون کلید F2 رو بزن و یا در حالی که دکمه ی کنترل رو نگه داشتی روش کلیک کن

برای بخش دوم سوالت اسلات ()on_btnAddToList_clicked رو ببین

----------


## armintirand

من این تابع روتوی  پیاده سازی سازنده کلاس Sell بکار بردم
    Connect(Combo,SIGNAL(currentIndexChanged(QString))  ,this,SLOT(on_btnAddToList_clicked()));

ولی برام جواب نداد میشه بگین اشکالش چیه؟
ممنون

----------


## alamate_aoal

کدت خیلی آشفته هست, من چیزی متوجه نشدم . 

اخیرا برای صرفه جویی در وقت به جای هفته ای دو بار حمام یک بار میرم و این یعنی یک snipped code اینجا بذار نه برنامه ی چند صد خطی :لبخند گشاده!:

----------


## armintirand

> من این تابع روتوی  پیاده سازی سازنده کلاس Sell بکار بردم
>     Connect(Combo,SIGNAL(currentIndexChanged(QString))  ,this,SLOT(on_btnAddToList_clicked()));
> 
> ولی برام جواب نداد میشه بگین اشکالش چیه؟
> ممنون


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

----------


## alamate_aoal

خدا رو شکر که مشکلتون حل شد
در خدمتیم

----------


## armintirand

ظاهرا مشکل من نمیخواد تموم بشه الان این تابع رو نوشتم
void SellTab::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);
    Table->setItem(row , 1 , item);
}
تا توی خونه دوم از هر ردیف هم همون آیتم رو اضافه کنه برنامه اجرا میشه ولی پیام میده
     QTableWidget: cannot insert an item that is already owned by another QTableWidget

و توی خونه دومهیچ مقداری قرار نمیده. من میخوام آیتم توی لاین ادیت رو هم به خونه دوم اضافه کنم و همینطور لاین ادیت های دیگه رو هم توی خونه های بعدی و بعد برم سراغ قراردادن محتوای جدول توی دیتابیس.

----------


## alamate_aoal

باید کلون بگیری

void SellTab::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);
    Table->setItem(row , 1 , item->clone() );
}

----------


## armintirand

عجب نکته کنکوری جالبی فرمودین اینی که شما گفتین کار کرد ولی حالا ببینین برای ارسال از لاین ادیت چیکار کردم:
اول دوتا تابع کانکت توی سازندم اضافه کردم
   connect(LnEdit2,SIGNAL(textChanged(QString)),this,  SLOT(set_LnEdit2(QString)));
    connect(LnEdit2,SIGNAL(editingFinished()),this,SLO  T(set_LnEdit2Table()));
بعد دوتا اسلات تعریف کردم
void SellTab::set_LnEdit2(QString a)
{
    i_LnEdit2 = a;

}

void SellTab::set_LnEdit2Table()
{
//    qDebug() <<i_LnEdit2;
    int row = Table->rowCount();
    qDebug() << row;
    Table->setRowCount( row );
    QTableWidgetItem *item = new QTableWidgetItem ;
    item->setText(i_LnEdit2);
    Table->setItem(row , 1 , item());
}
که تو اولی هر تغییر در لاین ادیت رو میریزه توی متغییر i_LnEdit2 و تو دومی بعد از اینکه از لاین ادیت خارج شدیم انجام میشه و باید توی خانه دوم جدول در همون ردیف جاری آیتم رو قرار بده ولی کار نمیکنه جالب اینه که وقتی مینویسم 
Table->setRowCount( row + 1 );
کار میکنه ولی خیلی خنده دار یعنی میاد توی خانه دوم ردیف بعدی که ایجاد میکنه آیتم اضافه میکنه ولی وقتی میگم تو سطر جاری اضافه کنه کار نمیکنه.
فکر کنم مثل همون نکته کنکوری اینم باید یک نکته داشته باشه.
ممنون

----------


## armintirand

دوست عزیز منو دریاب. امیدم به شماست اگه ممکنه اینم بگین.(البته ظاهرا خیلی سریش شدم شرمنده انشاا... جبران میکنم.)

----------


## rubiks.kde

دلیلش بخاطر هماهنگ نبودن شمارش گر سطر ها و set کردن نادرست item است برای مثال فرض کن تعداد سطرهات یکی باشه حالا اون متغییر row برابر با یک میشه ولی وقتی داری item رو set میکنی واسه سطر یک set میکنی در حالی که شروع ایندکس ها از صفر میباشه و شما باید برای سطر صفر این کار رو انجام بدی (اگه دقت داشته باشید گفتید که زمانی تعداد سطرها رو یکی اضافه میکنید واسه سطر بعدی این کار رو میکنه که دقیقا همون چیزیه که گفتم در واقع تعداد سطرها یکی بیشتر از شماره اندیس مربوط به سطر می باشد ) حال اگه یه واحد از row هنگامی که میخوایی set کنی کم کنی میبینی درست میشه

من هم یک مثال مثل این چیزی که گفتید نوشتم و این کارهایی که گفتم رو انجام دادم درست کار کرد

----------


## alamate_aoal

نه قربونت برم سریش نیستی
فکر میکنم جواب سوالت رو از پست بالایی گرفتی , درسته ؟

راستی در خط 15 از کد بالا اون پرانتز item برای چیه؟

چند تا پیشنهاد :
نیازی به استفاده از اسلات set_LnEdit2 نیست , می تونید مقدار Line Edit رو مستقیم بخونید.
من فکر می کنم استفاده از سیگنال editingFinished برای دریافت اطلاعات به اینصورتی که شما دارید استفاده می کنید جالب نیست. فرض کن Line Edit فوکوس داره اونوقت کاربر بر روی دکمه ی  Close  کلیک میکنه , قطعا چیزی که مد نظر ش نبوده رخ میده.

----------


## armintirand

> دلیلش بخاطر هماهنگ نبودن شمارش گر سطر ها و set کردن نادرست item است برای مثال فرض کن تعداد سطرهات یکی باشه حالا اون متغییر row برابر با یک میشه ولی وقتی داری item رو set میکنی واسه سطر یک set میکنی در حالی که شروع ایندکس ها از صفر میباشه و شما باید برای سطر صفر این کار رو انجام بدی (اگه دقت داشته باشید گفتید که زمانی تعداد سطرها رو یکی اضافه میکنید واسه سطر بعدی این کار رو میکنه که دقیقا همون چیزیه که گفتم در واقع تعداد سطرها یکی بیشتر از شماره اندیس مربوط به سطر می باشد ) حال اگه یه واحد از row هنگامی که میخوایی set کنی کم کنی میبینی درست میشه
> 
> من هم یک مثال مثل این چیزی که گفتید نوشتم و این کارهایی که گفتم رو انجام دادم درست کار کرد


ببینید توی دستور پایین
void SellTab::set_LnEdit2Table()
{
    int row = Table->rowCount();
    qDebug() << row;
    Table->setRowCount( row - 1);
    QTableWidgetItem *item = new QTableWidgetItem ;
    item->setText(i_LnEdit2);
//    Table->setItem(row , 1 , item->clone());
    Table->setItem(row , 1 , item);
}
من یک دستور Qdebug گداشتم متغییر row رو برام چاپ میکنه و چون اونو از خود جدول میگیره سطریه میخوام توی خونه دومش آیتم اضافه کنم پس نباید مشکلی باشه.حتی من بخاطر حرف شما اومدم از row یک واحد کم کردم(تو کد بالا اینکارو کردم) نتیجه این شد که وقتی comboBox تغییر میکنه جدول یک ردیف اضافه میکنه و توی خونه اول آیتم اضافه میکنه و بعد از اینکه لاین ادیت تغییر میکنه و از اون خارج میشم اون ردیف جدول کم میشه.این نشون میده که اگه یک واحد کم نمیکردم باید جواب میداد که نداد.
ببخشید من متوجه نمیشم مشکلم از کجاست میشه واضحتر بگین؟(شرمنده)
ممنون

----------


## rubiks.kde

منظورم این بود که فرض کن برای بار اول این برنامه اجرا میشه شما هیچ سطری نداری اون وقت زمانی که از این تابع int row = Table->rowCount(); استفاده میکنی خروجی صفر میده حالا توی خط بعدی داری خودت تعداد سطرها رو صفر معرفی میکنی با این تابع Table->setRowCount( row); خوب هیچ تغییری نمیکنه شما برای این کار باید مثل کد زیر عمل کنی ببین چه نتیجه ای میگیری

void SellTab::set_LnEdit2Table()
{
    int row = Table->rowCount();
    qDebug() << row;
    Table->setRowCount( row);
    QTableWidgetItem *item = new QTableWidgetItem ;
    item->setText(i_LnEdit2);
//    Table->setItem(row , 1 , item->clone());
    Table->setItem(row - 1 , 1 , item);
}




چون همیشه باید تعداد سطرهات یکی بیشتر باشه

----------

