LINUX.ORG.RU

Связка alternatingRowColors+SelectRows: хомячка разрывает на части

 , , ,


0

4

Привет, ЛОР.

Программа – хеллоуворлд на Qt Widgets, на главное окно кинут QTableView. В классе объявлен указатель mdl на QStandardItemModel. В конструкторе после setupUi() пишем буквально следующее:

    mdl = new QStandardItemModel(4, 4, this);
    mdl->setItem(0, 0, new QStandardItem("One"));
    mdl->setItem(1, 1, new QStandardItem("Two"));
    mdl->setItem(2, 2, new QStandardItem("Three"));

    ui->tableView->setModel(mdl);

    ui->tableView->setShowGrid(false);
    ui->tableView->setAlternatingRowColors(true);
    ui->tableView->setStyleSheet(
        QString("QTableView { alternate-background-color: %1; background: %2 }")
        .arg("#b2b3ff").arg("#ffffff"));
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);

Должна получиться примерно такая картинка. Скриншот взят из Qt 6 (Manjaro с последними обновлениями), но такой же результат виден и в Qt 5.15.3 (старая Федора), и в Qt 4.8 (специальные сборки).

А в Qt 5.15.19 (та же манжара с последними обновлениями) и 5.15.18 (Альт p11) картина меняется: в строках, подсвеченных «альтернативным» цветом, ячейки заключаются в какие-то страшные рамки. Принципиален вызов setSelectionBehavior(SelectRows): если выбрать выделение отдельных ячеек, эффекта нет. В Манжаре пробовал KDE как с Wayland-сессией, так и с X11, разницы нет (вот среды, отличные от KDE, ещё не пробовал).

Желающим навести критику на setStyleSheet(): он картины особо не меняет, если его закомментарить, просто пропадёт второй цвет, но страшные недорамки остаются.

И да, я в курсе про Qt5 EOL, но вроде бы как в последних версиях все такие мелочи должны были быть вычищены, а не наоборот?

И более того, я не уверен, что тут вообще виновата Qt, поскольку ещё в начале августа в манжаре всё было нормально. Потом в конце августа – начале сентября я был в отъезде, вернулся. На прошлой неделе обновился – и вот такое. А Qt 5.15.19 в манжару прилетела ещё в мае… Похоже на какие-то сопутствующие пакеты.

Кто сталкивался с подобным эффектом и куда копать? Да, вариант «отказаться от всех Qt, кроме Qt6» я знаю, мне он пока не интересен. Интересно понять, что за фигня.

Обновление: спасибо всем откликнувшимся! Это глюк стиля Breeze. Программное переключение на другой стиль посредством QApplication::setStyle() решает проблему.

★★★★★

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

вроде бы как в последних версиях все такие мелочи должны были быть вычищены, а не наоборот?

В 4.8 по сравнению с 4.7 они сломали QSqlRelationalTableModel. Так что не исключено, что поломали, и им пофиг.

unC0Rr ★★★★★
()
Ответ на: комментарий от wandrien

Кстати да, хороший совет от иишки - попробовать с другим стилем. Стили могут по-разному реагировать на кастомизацию при помощи stylesheet, вплоть до полного игнора для целых контролов.

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

Там походу первый разбор ситуации конфабулированный, модель «читала» код по памяти, не скачивая сорцы.

Ко второму стоит присмотреться.

wandrien ★★★★
()

Лучше на Fusion стиле проверять. Несколько раз ловил глюки на KDE'шных стилях, глючило выделение мышкой в списках помещённых в dock виджеты.

Dr64h ★★★★
()
Ответ на: комментарий от wandrien

Не зря я боюсь скруглений.

Короче, все на kvantum!

Shadow ★★★★★
()
Последнее исправление: Shadow (всего исправлений: 1)
Ответ на: комментарий от wandrien

Проверка еще одной моделью:


2. Что именно ломается (проверенная цепочка)

  1. Коммит aba0f922 «Make viewItemPrimitive rounded like in QtQuick style» (25.02.2026) заменил в ветке отрисовки альтернативного фона setPen(Qt::NoPen); drawRect() на вызов Helper::renderViewItemPosition(..., QColor()). Это видно в самом патче.
  2. В renderViewItemPosition() ветка case QStyleOptionViewItem::Invalid делает painter->setBrush(bg); painter->setPen(outline); drawRect(rect); — с невалидным QColor() в качестве пера (в master строки те же; в v6.6.0 функции ещё нет вовсе).
  3. Qt 5.15 не заполняет QStyleOptionViewItem::viewItemPosition. В qtableview.cpp ветки 5.15 нет ни одного присваивания (в Qt 6.8 есть: Beginning/Middle/End, и явный opt.viewItemPosition = ... в drawCell). Зонд на Qt 5.15.15: 16 вызовов PE_PanelItemViewItem из 16 — viewItemPosition = 0 (Invalid), и при SelectRows, и при SelectItems.
  4. Невалидный QColor() как перо рисуется чёрным. Штрих 1 px с антиалиасингом поверх #b2b3ff даёт #59597f/#595a80.
  5. При выделении ячеек Breeze сам ставит OnlyOne (if (abstractItemView->selectionBehavior() != SelectRows) viewItemPosition = OnlyOne;) — ветка Invalid не исполняется, рамок нет. Совпадает с наблюдением автора треда.
  6. В Qt 6 ячейки таблиц намеренно рисуются с Invalid-позицией, но там outline = focusColor — валидный цвет, а renderFocusRect() при невалидном контуре делает setPen(Qt::NoPen). Поэтому Qt6 не затронут.
  7. Маржины, ради которых всё затевалось, к таблицам не применяются вообще: if (!qobject_cast<const QTableView *>(actualWidget)) rect = rect.marginsRemoved(...). Отсюда рамка ровно по границам ячеек.

4. Что делать автору треда

QT_STYLE_OVERRIDE=Fusion ./your_app     # 5 секунд: рамки пропали → виноват Breeze, а не Qt
pacman -Q breeze5                       # у манжаровых — 6.7.5-1
# откат: sudo pacman -U /var/cache/pacman/pkg/breeze5-6.6*.pkg.tar.zst (или из архива Arch)

В приложении: QApplication::setStyle("Fusion"); либо оформлять фон самим QSS (QTableView::item { background: #ffffff; } QTableView::item:alternate { background: #b2b3ff; } — панель рисует QStyleSheetStyle в обход Breeze); либо QProxyStyle, перекрывающий PE_PanelItemViewItem.

Репорт: bugs.kde.org → Breeze → QStyle, фикс — одна строка в Helper::renderViewItemPosition(). Смежный баг того же коммита уже есть: 523118 (элизия текста, RESOLVED FIXED, ссылается на aba0f922; See Also: 524738). Регрессия с рамками, судя по поиску в Bugzilla, ещё не заведена — то есть это реальная недоработка breeze5 6.7.x, а не фантазия.

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

Таки да. Fusion, Oxygen и Windows работают нормально. Это действительно глюк Breeze.

Заодно я разобрался с QStyleFactory и ввёл в свою программу интерактивный выбор стиля. Надо будет и в DoubleContact такой выбор сделать…

hobbit ★★★★★
() автор топика
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от hobbit

Заодно я разобрался с QStyleFactory и ввёл в свою программу интерактивный выбор стиля.

Там не хватает чекбокса «Оставить стиль по умолчанию». Кроме того, отсутствует возможность выбора файла со стилем пользователя.

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

чекбокса «Оставить стиль по умолчанию»

Она при первом заходе в настройки пытается спозиционироваться на него, если в настройках имя не было записано. Но да, отдельную галку для возврата на умолчальное значение надо бы сделать. У меня так для форматов даты и времени сделано.

выбора файла со стилем пользователя.

.qss?

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

По большей части да. Ещё в оффтопике есть довольно уродливые и неудобные вещи. Но именно кроссплатформенные библиотеки виновники торжества электронов и иже с ними.

peregrine ★★★★★
()
Ответ на: комментарий от hobbit

QApplication::setStyle(QString) подгружает стили из плагинов, обычно плагины грузятся из QCoreApplication::applicationDirPath(), либо из QTDIR (/usr/lib/qt*/plugins), конкретно плагины стилей подгружаются из подкаталога styles.

Здесь подробней:

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

Я когда делал наброски с загрузчиком плагинов, намаялся, у Qt6 есть нужные функции для QStyle и QLibraryInfo::paths() для получения путей, а вот для старых версий приходится самому колдовать код с путями.

Dr64h ★★★★
()
Ответ на: комментарий от peregrine

Просто чтобы мы понимали друг друга:

Кроссплатформенные библиотеки, написанные на вебне, являются причиной популярности веб-интерфейсов?

Я ведь правильно все понял? Получается, что вебинар популярен потому что смог сделать настоящую кроссплатформенность. Не, ну так-то логично.

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

Кроссплатформенные библиотеки, написанные на вебне, являются причиной популярности веб-интерфейсов?

Нет, очень некачественные кроссплатформенные библиотеки сделанные на C/C++/Java (GTK, WxWidgets, FLTK, Qt, JavaFX, Swing, AWT, SWT) являются причиной популярности «тормознутого» веба, который таки смог в гибкий программируемый интерфейс (Qt вон завезли ради этого QML, который с веба содран, но не полноценный веб). А вокруг Vulkan/OpenGL напрямую чтоб UI писать никто ничего удобного так и не сделал. Задача таких библиотек быть простыми в использовании, гибкими они не будут, если не работают напрямую с GPU или каким-то виртуальным рендером на CPU. А простыми её только в дельфях, да в Visual Studio в виде WinForms делали. Но если тебе просто пару кнопок и полей ввода надо, то ты про гибкость не поймёшь. Попробуй свой календарь написать с кликабельными датами и заметками и чтоб он стильно выглядел, чтоб понять и почувствовать чем же веб лучше. Да даже на Canvas всё отрисовать проще будет.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от peregrine

QML - это диалект яваскрипта, гуишный фреймворк называется Qt Quick.

css+js+html удобнее даже без всяких фреймворков

Ну-ну. OpenGL с Vulkan уже забыты?

unC0Rr ★★★★★
()
Последнее исправление: unC0Rr (всего исправлений: 1)
Ответ на: комментарий от unC0Rr

Ну и самое главное: css+js+html бесплатно и никто мне не мешает им пользоваться, Qt проприетарщина (опенсорс версия отличается в худшую сторону) соблюдающая санкции.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от peregrine

никто мне не мешает им пользоваться

опенсорс версия отличается в худшую сторону

Не отличается для целей гуестроения. Плюс, опенсорсная версия - это то, что в каждом дистрибутиве линукса.

unC0Rr ★★★★★
()
Ответ на: комментарий от peregrine

Почти тоже самое: веб лучше нативных библиотек, но не потому, что он великолепен, а потому, что другие ужасны.

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

Qt проприетарщина

Злостное 4.2. В Qt есть некоторые модули, доступные только под GPL либо коммерческой лицензией, но основная и самая ценная масса кода доступна ещё и под LGPL. А в GPL-проекте я и GPL-модули Qt могу использовать. Это раз.

Ты определись, ты пишешь про свободу или про бесплатность. Это два.

Санкции санкциями, но репа с исходниками Qt доступна, и свободные лицензии на этот код никто не отменял. Это три.

И в целом, убедительная просьба не устраивать в технической теме (тем более, мой вопрос уже решили и даже выяснили, что проблема была не в Qt) сеанс чёрного пиара с перевиранием фактов. Это четыре.

hobbit ★★★★★
() автор топика
Последнее исправление: hobbit (всего исправлений: 2)
Ответ на: комментарий от hobbit

Мне в опенсорс проекте нужен был какой-то кусок Qt, кажется QtCharts, я нашёл, обрадовался и открыв сайт (ещё во времена ковида до санкций) очень расстроился, увидев что только в платной версии, то что в опенсорсе было то-ли с багом, то-ли с очень плохой производительностью, то-ли без какой-то фичи нужной, а ждать пол года когда из коммерческой версии прилетит пофикшенный код ну такое… Т.е. по факту их GPL не полноценный, а объедки от основной версии, в которых даже баги не фиксят.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 2)
Ответ на: комментарий от peregrine

Раньше на flash ui делали. Я так и не понял,счем он лучше Tk - по мне был хуже во всём.

Shadow ★★★★★
()
Ответ на: комментарий от peregrine

Мне в опенсорс проекте нужен был какой-то кусок Qt, кажется QtCharts, я нашёл, обрадовался и открыв сайт (ещё во времена ковида до санкций) очень расстроился, увидев что только в платной версии

QtCharts доступен под GPL и коммерческой лицензией. В LGPL его нет. Что у тебя там было с багом и производительностью, я не понял, шла ли речь про сам QtCharts или про какой-то его «обрезанный» аналог… Если про баг в предыдущей версии самого QtCharts, тебе никто не запрещает поправить его самому. GPL – про доступность кода, а не про то, что тебе вовремя и на блюдечке приносят все фиксы.

У меня есть вопросы к кутешникам, этот их сомнительный запрет на смешение лицензий, которым они наказывают в первую очередь себя, например (и тех, кто хочет купить коммерческую лицензию, ЛОЛ, опенсорс это не затрагивает). Но с «проприетарной Qt» и «неполноценной GPL» ты передёргиваешь.

hobbit ★★★★★
() автор топика
Последнее исправление: hobbit (всего исправлений: 2)
Ответ на: комментарий от peregrine

А простыми её только в дельфях, да в Visual Studio в виде WinForms делали

Ну уж нет, приходилось мне этот ужас терзать. Слава богу, я сейчас на Qt.

next_time ★★★★★
()
Ответ на: комментарий от peregrine

Попробуй свой календарь написать с кликабельными датами и заметками и чтоб он стильно выглядел

А что, на js есть варианты? Так-то все календари, да вообще любой интерактив на js делается довольно ужасным образом. Свистелки и перделки - да, легко. А вот элементарно текстовый редактор нормальный написать - уже всё, уже никак. Взять, хотя бы, текстовый редактор ЛОРа, как пример: 20 лет сайт пишут, а он даже не WYSIWYG. И везде в вебне также.

next_time ★★★★★
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария