Size: a a a

2020 May 01

JN

Joy Narical in Qt
Anatoly Shirokov
Исходники у тебя в utf-8 без BOM?
как бы проверить это?
источник

AS

Anatoly Shirokov in Qt
Joy Narical
как бы проверить это?
Если текстовый файл начинается на U+FEFF, то это utf-8 с bom
источник

AS

Anatoly Shirokov in Qt
А так, надо сообщить msvc, что исходники у тебя utf-8
источник

AS

Anatoly Shirokov in Qt
источник

JN

Joy Narical in Qt
Anatoly Shirokov
Исходники у тебя в utf-8 без BOM?
C source, UTF-8 Unicode (with BOM) text
источник

AS

Anatoly Shirokov in Qt
Joy Narical
C source, UTF-8 Unicode (with BOM) text
Короче, кинь приятелю ссылку выше. Пусть в опциях компилятора установит /utf-8
источник

JN

Joy Narical in Qt
Anatoly Shirokov
Короче, кинь приятелю ссылку выше. Пусть в опциях компилятора установит /utf-8
Заработало. Спасибо огромное
источник
2020 May 02

M

Mr.Mait in Qt
Всем привет. Помогите отловить магию(это точно магия). Минимальный пример приложу.
Имеем QListWiget и две кнопки Add(добавляет итем) и Remove(удаляет итем).
Сделал так, что при старте программы свойство enabled у кнопки remove = false.

При клике по итему в QListWiget, срабатывает сигнал currentRowChanged. Там проверяю что row не отрицательный и меняю свойство enabled у кнопки remove = true и наборот на false, если row == -1(т.е. у QListWiget закончились итемы)

Нормальная последовательность: добавить пару итемов(больше одного), удалить(хоть все). Программа работает отлично, как и задумано. Когда заканчиваются итемы, кнопка Remove становится неактивной.

Магия (при первом запуске программы):
* Добавить итем.
* Выбрать итем.
* Удалить итем.
* После удаления прилетают два сигнала currentRowChanged, вместо одного.
Должно было быть так:
ADD "Item 0"
CHANGE  row: 0  addr: 0x12f0fb0 " text: Item 0
REMOVE "Item 0"
CHANGE  row: -1  addr: 0x0 ""
А получилось так:
ADD "Item 0"
CHANGE  row: 0  addr: 0x12f0fb0 " text: Item 0"
REMOVE "Item 0"
CHANGE  row: -1  addr: 0x0 "" <------- OK
CHANGE  row: 0  addr: 0x12f0fb0 " text: Item 0" <------ WTF?
Т.е. удалили единственный итем, приходит сигнал что менятся выбранная строка на -1, потом следом второй сигнал и выбранная строка теперь 0 и откуда-то появляется призрачный удаленый итем.

Если программу изменить так, чтобы кнопка Remove всегда имело свойство enabled = true и не менять enabled у кнопки remove, то Магия не воспроизводится.

Я предпологаю что Магия из-за того что по сигналу currentRowChanged в слоте вызываю у кнопки setEnabled

Тестировал на линуксе 5.7 и на винде 5.11. Все точно так же воспроизводится баг.

Может я туплю?
источник

M

Mr.Mait in Qt
источник

AS

Anatoly Shirokov in Qt
Anatoly Shirokov
#bug бага или фича? говорят, замечено еще в Qt 4.6.3.

Qt 5.9.3: В ListWidget четыре элемента Item1, Item2, Item3, Item4:
void MainWindow::on_pushButton_clicked() {
 if (ui->listWidget->currentRow() < ui->listWidget->count()) {
   qDebug() << "before delete: currentRow =" << ui->listWidget->currentRow();
   auto item = ui->listWidget->takeItem(ui->listWidget->currentRow());
   if (item) {
     qDebug() << item->data(Qt::DisplayRole) << " has been deleted";
     delete item;
     qDebug() << "afted delete: currentRow =" << ui->listWidget->currentRow();
   }
 }
}

void MainWindow::on_listWidget_currentRowChanged(int currentRow) {
 qDebug() << "current row changed " << currentRow;
}

void MainWindow::on_listWidget_itemSelectionChanged() {
 qDebug() << "item selection changed " << ui->listWidget->currentRow();
}

void MainWindow::on_listWidget_currentItemChanged(QListWidgetItem *current,
                                                 QListWidgetItem *previous) {
 qDebug() << "current item changed: current = "
          << (current ? current->data(Qt::DisplayRole) : "null")
          << ", previous = "
          << (previous ? previous->data(Qt::DisplayRole) : "null");
}


Удаляю Item3:
current item changed: current =  QVariant(QString, "Item3") , previous =  QVariant(QString, "null")
current row changed  2
item selection changed  2
before delete: currentRow = 2
item selection changed  3 << WARNING! после удаления будет недействительным
current item changed: current =  QVariant(QString, "Item4") , previous =  QVariant(QString, "Item3")
current row changed  3 << WARNING! после удаления будет недействительным
QVariant(QString, "Item3")  has been deleted
afted delete: currentRow = 2

Забавно, пока физически Item не удален, currentRowChanged и itemSelectionChanged вызываются с неверным параметром 3, хотя после физического удаления item-a, currentRow восстанавливает верное значение, но без оповещения. А вот currentItemChanged ведет себя как надо, полагайся на него currentItemChanged.
@mr_mait это не одного поля ягоды?
источник

M

Mr.Mait in Qt
Anatoly Shirokov
@mr_mait это не одного поля ягоды?
Не, вроде немного по другому. У меня то все отлично, когда не меняю свойство setEnabled у кнопки в слоте. Если меняю свойство у кнопки по сигналу currentRowChanged , то почему-то от listWidgeta прилетает  два сигнала currentRowChanged, вместо одного. Я то listWidget не трогал. Только кнопку...
источник

F

FPOHTMEH in Qt
Mr.Mait
Не, вроде немного по другому. У меня то все отлично, когда не меняю свойство setEnabled у кнопки в слоте. Если меняю свойство у кнопки по сигналу currentRowChanged , то почему-то от listWidgeta прилетает  два сигнала currentRowChanged, вместо одного. Я то listWidget не трогал. Только кнопку...
Попробуй использовать только currentRow, currentItem - нет. Может они не синхронизированы, для них ведь разные сигналы
источник

M

Mr.Mait in Qt
Для облегчения скину новый пример. Закомментить 55 строку в widget.cpp, будет один сигнал currentRowChanged, если раскомментить, будут два сигнала currentRowChanged. Делать как выше описывал с магией.
источник

M

Mr.Mait in Qt
источник

F

FPOHTMEH in Qt
Mr.Mait
Для облегчения скину новый пример. Закомментить 55 строку в widget.cpp, будет один сигнал currentRowChanged, если раскомментить, будут два сигнала currentRowChanged. Делать как выше описывал с магией.
Проверить твой код я сейчас не могу, только посоветовал не использовать currentItem & currentRow вместе, так как здесь может быть рассинхрон, отсюда и баги
источник

M

Mr.Mait in Qt
Просто вот это строка ui->pushButtonRemove->setEnabled(row != -1) в слоте от сигнала currentRowChanged влияет на поведение listWidget сигнала currentRowChanged

Но за рассинхрон подумаю...
источник

AS

Anatoly Shirokov in Qt
Mr.Mait
Просто вот это строка ui->pushButtonRemove->setEnabled(row != -1) в слоте от сигнала currentRowChanged влияет на поведение listWidget сигнала currentRowChanged

Но за рассинхрон подумаю...
это о том баге выше, что я приводил
источник

AS

Anatoly Shirokov in Qt
используйте itemChanged, rowChanged не используй
источник

M

Mr.Mait in Qt
Anatoly Shirokov
используйте itemChanged, rowChanged не используй
Да, хорошо, попробую
источник

B

Bril in Qt
У меня currentRowChanged из примера вообще не посылается, и я туплю почему так
источник