LINUX.ORG.RU

Qt QComboBox->clear()


0

1

Здравствуйте! Начал разработку небольшого проекта на Qt (для получения опыта). И во время разработки столкнулся с одной проблемой. При выполнении QComboBox->clear() программа вылетает. Гугление подсказало, что происходит это из за того, что этот QComboBox используется более, чем одним слотом (поправьте, если не так). В общем сам вопрос: можно ли каким-то образом отключить второй слот во время очистки и повторного заполнения QComboBox'а? Существуют ли другие пути решения этой проблеммы?



Последнее исправление: masb8ly (всего исправлений: 1)

что за clean?

$ wget http://qt-project.org/doc/qt-5.0/qtwidgets/qcombobox.html -O- -q | grep clean

программа вылетает

запустить под отладкой, посмотреть где вылетает?

anonymous
()
Ответ на: комментарий от anonymous

что за clean?

Извиняюсь, опечатался. Clear.

запустить под отладкой, посмотреть где вылетает?

Не отладкой, но методом исключения обнаружил, что как раз на clear вылетает. Причем только когда QComboBox используется другим слотом.

Ничего не понял... Код?

void MainWindow::on_ProcBrendCB_currentIndexChanged(const QString &arg2)
{
    ProcBase.clear();
    if (arg2 == "All")
    {
        QSqlQuery All("SELECT Name FROM Proc");
        while (All.next())
        {
            QString name = All.value(0).toString();
            ProcBase.append(name);
        }
    }
    else
    {
        QSqlQuery Brend("SELECT Name FROM Proc WHERE Brend='"+arg2+"'");
        while (Brend.next())
        {
            QString name = Brend.value(0).toString();
            ProcBase.append(name);
        }
    }
    ui->ProcNameCB->clear();
    ui->ProcNameCB->addItems(ProcBase);
}

Вылет происходит на предпоследней строке «ui->ProcNameCB->clear();».

masb8ly
() автор топика
Ответ на: комментарий от masb8ly

только если однопоточный код:

void MainWindow::on_ProcBrendCB_currentIndexChanged(const QString &arg2)
{
    static int tmp = 0; if(tmp!=0) return; tmp++;
    ProcBase.clear();
    if (arg2 == "All")
    {
        QSqlQuery All("SELECT Name FROM Proc");
        while (All.next())
        {
            QString name = All.value(0).toString();
            ProcBase.append(name);
        }
    }
    else
    {
        QSqlQuery Brend("SELECT Name FROM Proc WHERE Brend='"+arg2+"'");
        while (Brend.next())
        {
            QString name = Brend.value(0).toString();
            ProcBase.append(name);
        }
    }
    ui->ProcNameCB->clear();
    ui->ProcNameCB->addItems(ProcBase);
    tmp--;
}

anonymous
()
Ответ на: комментарий от anonymous

нажать Ok и посмотреть на какой строчке, это интересует.

Вот в этой строке «{ Q_ASSERT(i >= 0); return QCharRef(*this, i); }» в файле qstring.h

masb8ly
() автор топика
Ответ на: комментарий от masb8ly

Окно->Обзоры->Стек, в этом окне опуститься до файлов с вашим кодом, там будет указана строка, в которой произошла ошибка.

anonymous
()
Ответ на: комментарий от masb8ly

этот код запрещает рекурсию функции MainWindow::on_ProcBrendCB_currentIndexChanged, если проблема была бы из-за неё.

anonymous
()

каким-то образом отключить второй слот во время очистки и повторного заполнения QComboBox'а?

blockSignals(true)

QComboBox используется более, чем одним слотом

более чем одним потоком, синхронизировать работу с объектом через QMutex

anonymous
()
Ответ на: комментарий от anonymous

Окно->Обзоры->Стек, в этом окне опуститься до файлов с вашим кодом, там будет указана строка, в которой произошла ошибка.

Немного не понял где тут ошибка. Вот скриншоты всего, что вывело в этом окне: 1. http://s020.radikal.ru/i713/1308/19/7808ccc1731d.png 2. http://s018.radikal.ru/i511/1308/cf/af4d10ef8900.png

masb8ly
() автор топика
Ответ на: комментарий от anonymous

и есть ли ещё они же в стеке?

anonymous
()
Ответ на: комментарий от anonymous

конкретно упало оно у тебя в 5-той строчке того стека. функция MainWindow::on_ProcName_CB_currentIndexChanged

anonymous
()
Ответ на: комментарий от anonymous

Это как раз те функции, котырые используют комбобокс этот. Суть тут вот в чем: Функция в строке 5 работает с внешними виджетами. Тоесть по изменению индекса в этой функции из базы запрашиваются данные и передаются в другие виджеты. Функция в строке 17 работает с двумя QComboBox'ами. По изменению в одном из них она должна очистить другой и заполнить новыми данными. Как раз этот «другой» используется в функции 5.

masb8ly
() автор топика
Ответ на: комментарий от masb8ly

покажи функцию MainWindow::on_ProcName_CB_currentIndexChanged или окрестности 65-той строки файла mainwindow.cpp, вероятно обращение к несуществующему индексу QString-а

anonymous
()
Ответ на: комментарий от anonymous
    ui->ProcNameCB->blockSignals(true);
    ui->ProcNameCB->clear();
    ui->ProcNameCB->blockSignals(false);
    ui->ProcNameCB->addItems(ProcBase);

Это решило проблему, но как я понимаю это скорее костыль, чем решение. Хотелось бы получить более правильное решение проблемы.

masb8ly
() автор топика
Ответ на: комментарий от anonymous

даже я бы сказал к отрицательному элементу QString-а. а вот и доказательство:

Вот в этой строке «{ Q_ASSERT(i >= 0); return QCharRef(*this, i); }» в файле qstring.h

anonymous
()
Ответ на: комментарий от anonymous
QSqlQuery Bench("SELECT Bench FROM Proc WHERE Name='"+arg1+"'");
    Bench.first();
    QString BenchTemp = Bench.value(0).toString();
    if ((BenchTemp[BenchTemp.length()-2] == '1') || (BenchTemp[BenchTemp.length()-1] == '0' && BenchTemp[BenchTemp.length()-2] == '2'))
        ui->ProcTestBench->setText(Bench.value(0).toString()+" очков");
    else
    {
        if (BenchTemp[BenchTemp.length()-1] == '1')
            ui->ProcTestBench->setText(Bench.value(0).toString()+" очко");
        if (BenchTemp[BenchTemp.length()-1].digitValue() > 1 && BenchTemp[BenchTemp.length()-1].digitValue() < 5)
            ui->ProcTestBench->setText(Bench.value(0).toString()+" очка");
        if (BenchTemp[BenchTemp.length()-1].digitValue() > 4)
            ui->ProcTestBench->setText(Bench.value(0).toString()+" очков");

        QSqlQuery Pos("SELECT Pos FROM Proc WHERE Name='"+arg1+"'");
        Pos.first();
        ui->ProcTestPos->setText((Pos.value(0).toString())+" место");
    }

Вот с 62 по 79 строку.

masb8ly
() автор топика
Ответ на: комментарий от masb8ly

код:

BenchTemp[BenchTemp.length()-2]
вызывает ошибку, при пустой строке BenchTemp или при одном символе в BenchTemp.

anonymous
()
Ответ на: комментарий от anonymous

Одного символа там быть не может, а вот пустая строка появляется по вполне обьяснимым причинам. Все дело в том, что когда я очистил ProcNameCB то в ему не откуда брать значение, чтобы потом запросом искать этот BenchTemp. А соответственно BenchTemp остается пустым.

masb8ly
() автор топика
Ответ на: комментарий от masb8ly

ну если тебя не волнует, что сигналы эмитированные между true и false не были доставлены в слот - вполне себе решение.

QMutex* mutex = new QMutex;//где-то там

У синхронизируемых потоков должен быть один и тот же экземпляр мьютекса (Constructor(QMutex* m...) или setMutex(QMutex* m))

mutex->lock();
...
mutex->unlock();

anonymous
()
Ответ на: комментарий от anonymous

А собственно да. Проверил то в чем сомневался - работает. Значит проблем быть не должно. Всем огромнейшее спасибо за помощь!

masb8ly
() автор топика
Ответ на: комментарий от MikeDM

Если есть скайп или вк, то напиши, я отпишусь. Если не хочешь светить, то скинь на это мыло: dvgedz@gmail.com

masb8ly
() автор топика
Ответ на: комментарий от masb8ly

Мое мыло есть в профиле. но я сейчас тебе черкну на мыло мессагу.

MikeDM ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.