Тема: QT Подайте ідею як правильно "зв'язати" два comboBox

Є в мене два comboBox
перший це "категорія"
другий це "підкатегорія"
Інформацію вони черпають з БД там є таблиці з аналогічними назвами які зв'язані зовнішнім ключем, зв'язок "1 до багатьох"

І так, як зробити так що коли користувач вибере категорію в comboBox категорія то в comboBox з підкатегорією появилася відповідна інформація, напевно потрібно при події "поза фокусом" зразу занесення інформації з БД в comboBox підкатегорія

хто не зрозумів

спочатку в будь-якому разі перший comboBox отримує фокус, так що не залежно від того чи користувач просто перейде до наступного comboBox чи буде щось вибирати з першого і перейде до другого подій "поза фокусом" зпрацює і другий comboBox при обробці цієї події отримає потрібну інформацію з БД

я зробив функцію linkComboBox
перший параметр це категорія
другий підкатегорія

І тут є проблема, нижче поясню яка

template <typename Category,typename Subcategory>
void linkComboBox(Category *comboBoxCategory, Subcategory *comboBoxSubcategory)
{
    comboBoxCategory->addItems(listCategory());
    QObject::connect(
                comboBoxCategory,
                SIGNAL(FocusOut()),
                comboBoxCategory,
                SLOT(didChoice())
                );
}

didChoice - обробник події поза фокусом (не знаю чи правильно назвав, хотів назвати "зробленийВибір")

void MyComboBox::didChoice()
{
    if( this->findText( this->currentText() ) == -1 )
    {
        /*
            If the text is not in ComboBox then add this text
        */
        this->addItem( this->currentText() );
    }
    else
    {
        /*
            Find foreign key and insert list text
        */
        listSubcategory( this->currentText() );
    }
}
listCategory, вона працю як я хочу так що тут питань немає

QStringList listCategory()
{
    /*
        returns a list with categories of products
    */
    QSqlQuery *query = new QSqlQuery;
    query->exec("SELECT _name_ FROM category");
    QStringList list;

    while (query->next())
        list << (query->value("_name_").toString());

    delete query;
    return list;
}

Ну і проблемна функція

void listSubcategory( QString Text )
{
    QStringList list;

    /*
        If was insert a new entry then Subcategory will be empty
    */

    if(Text == "")
        return;

    int _id_ = -1;

    QSqlQuery *query = new QSqlQuery;

    query->prepare("SELECT _id_ FROM category WHERE _name_=:_name_");
    query->bindValue(":_name_", Text);
    query->exec();
    query->next();
    _id_ = query->value("_id_").toInt();

    query->prepare("SELECT _name_ FROM subcategory WHERE _categoryId_=:_id_");
    query->bindValue(":_id_", _id_);
    query->exec();

    while(query->next())
        list << query->value("_name_").toString();

    delete query;

    //? ui->comboBoxSubcategory->addItems( list );
}

А тепер про проблему, в кінці listSubcategory я закоментував проблемний рядок.
Справа в тому що я не знаю як listSubcategory передати Subcategory *comboBoxSubcategory, цю функцію викликає функція як обробляє подію (тобто didChoice) а вона вже немає об'єкта comboBoxSubcategory

Як передати об'єкт comboBoxSubcategory в listSubcategory  ?

2

Re: QT Подайте ідею як правильно "зв'язати" два comboBox

Давайте мабуть по пунктах:

  • В Делфі і Білдері master-detail робиться взагалі без коду, простим налаштуванням компонентів. Підозрюю, що в Qt також

  • Чому б не селектити id з category там же, де ви заповнюєте перший комбік? Треба буде лише десь цей список зберегти поки юзер не зробить вибір

  • Ваша функція могла б приймати на вхід вказівник на comboBoxSubcategory, але краще, щоб вона повертала список добутих значень. Тоді заповненням comboBoxSubcategory займатиметься той, хто викликав listSubcategory

Подякували: Betterthanyou1

3

Re: QT Подайте ідею як правильно "зв'язати" два comboBox

Torbins написав:

Давайте мабуть по пунктах:

  • В Делфі і Білдері master-detail робиться взагалі без коду, простим налаштуванням компонентів. Підозрюю, що в Qt також

Так я знайомий з Builder і використовував майстра для створення зв'язків, але в QT я довго шукав щось подібне так і не знайшов, тому нічого сказати не можу..., прийдеться кодить

Torbins написав:

[*]Чому б не селектити id з category там же, де ви заповнюєте перший комбік? Треба буде лише десь цей список зберегти поки юзер не зробить вибір[/*]

Не знаю навіщо, ну наприклад в мене буде лист цих ІД плюс ще й текст потрібно буде зберігати бо як мені дізнатися що вибрав користувач, можна більш детальніше що з цім списком мені робити дальше ?

Torbins написав:

[*]Ваша функція могла б приймати на вхід вказівник на comboBoxSubcategory, але краще, щоб вона повертала список добутих значень. Тоді заповненням comboBoxSubcategory займатиметься той, хто викликав listSubcategory[/*]

Коли я передаю якийсь параметр didChoice наприклад

QObject::connect(
                comboBoxCategory,
                SIGNAL(FocusIn()),
                comboBoxCategory,
                SLOT(didChoice(comboBoxSubcategory))
                );

то виникає в мене помилка, справа в тому що СИГНАЛ лише може передавати параметри СЛОТУ

Щодо того хто викликає

void MyComboBox::focusOutEvent(QFocusEvent *e)
{
    emit FocusOut();
}

це comboBoxCategory він теж не має comboBoxSubcategory


Я знайшов тимчасове рішення це оголосити глобальний QComboBox *comboBoxSubcategory_;
і в linkComboBox зробити присвоєння comboBoxSubcategory_ = comboBoxSubcategory;

4

Re: QT Подайте ідею як правильно "зв'язати" два comboBox

В Qt ідея в тому, що у вас має бути модель, яка відображається, зокрема, комбобоксами. Комбобокси прив'язуються до моделі, а вже модель має змінюватися, як вам треба.

Подякували: Betterthanyou1