Pull to refresh

Comments 43

Что я только сейчас прочитал? Уважаемый автор, вы сами-то статью читали? Простите, но это просто какой-то поток сознания, а не законченная статья.

И разрешите себе использовать «Ъ».

404 по ссылке на гитхаб.

В заголовке видео - Qt4. Вы отстали от жизни лет на 9. Уже даже под 5 кутэ не начинают разработку.

Использовать QLabel да еще и rich text для логов - зло. Будет работать толко если у вас очень мало логов.

Вызов слота по имени - это очень медленно.

Вы отстали от жизни лет на 9

Мне кажется отстал больше - лет на 14.
Но тут такой нюанс, что Qt 4 я довольно хорошо изучил (по исходникам если говорить).
Сделал свое развитие некоторых классов (QpTableView и т.д.), то есть добавил новый функционал.
А что в Qt 5, там все по прежнему (в части QtSql например), там все на уровне 2010г. Ну собственно сколько ждать-то еще...

Qt 5, если что, уже тоже не развивается. Релиз был в 2012, но существующие коммерческие продукты более-менее интенсивно стали переводить где-то в 2014-2017. В Qt5 только поддержка одной LTS версии осталась, и то минимальная. Уже очень давно есть Qt6 (именно 6, не 5). использовать Qt4 сейчас это примерно как начинать учиться программировать под windows 98 + mfc. А сигналы-слоты в Qt4 так вообще на макросах и строках. И, если не ошибаюсь, Qt4 это c++98, даже не c++03.

 Qt4 это c++98, даже не c++03

Да Qt 4 это C++98. И линакс просто С... И чем линакс плох?
В С++ 98 абстрактные классы есть, без лямбд мы обойдемся, R-value тоже не горит.
Но главное, без Qt5,6,7,8 можно прекрасно жить.

сигналы-слоты в Qt4 так вообще на макросах и строках

Но ведь работает? Я лично привык и мне не мешает (вроде бы)

использовать Qt4 сейчас это примерно как начинать учиться программировать под windows 98

Можно еще 3.11 вспомнить, учится никогда не навредит. Дело в удобстве, кто к чему привык и новых возможностях. Для меня Qt5 это не новые возможности, это больше новый гемморой.

Уже есть Qt6, чего вы к пятому прицепились.

Уже есть Qt6

Скоро 7 будет, тут нельзя останавливаться

Много без чего можно обойтись, но зачем?

Я вот когда-то лямбды в C++ не понимал, потом распробовал, и не знаю теперь, как раньше жил без них.

404 по ссылке на гитхаб.

Спасибо, исправил

Похоже не исправили, по прежнему 404

Похоже не исправили, по прежнему 404

да public забыл (как обычно), исправил

В ролике на ютубе, как и тут - 404

Использовать QLabel да еще и rich text для логов - зло

Соглашусь, но это не принципиально, можно как угодно реализовать и не на QLabel.

Вызов слота по имени - это очень медленно

А куда торопиться? Вы вызываете slot один раз, потом идет процесс 1,2,3 секунды к примеру. А вы боретесь за миллисекунды (или даже за микросекунды), зачем?

Вы, видимо, никогда не писали приложений с более-менее сложным UI и для мониторов с расширением выше HD, типа редакторов для игр.

Вы, видимо, никогда не писали приложений с более-менее сложным UI

Да и не планирую пока

Из текста непонятно зачем там вообще QVariant, invokeMethod и использование таймера. Хотелось бы глянуть на исходники, но это, видимо, приватный проект на гитхабе...

Из текста непонятно зачем там вообще QVariant, invokeMethod

QVariant удобен свой универсальностью. Для одних объектов (вызывая их слот) вы возвращаете один тип (класс 1), для других объектов другой тип (класс 2) и т.д. Но функция у вас на все времена одна (call_slot), к тому же статическая (удобно вызывать из любого файла cpp). Вот к примеру, если я хочу применить окно индикации я вызываю слот у объекта примерно так:

    QVariant retVal;

    qp_gui::call_slot( this ,

                       appDef::currentKKT_ ,

                       "Открытие смены",

                       QString("Открываем смену \n%1 %2")
                       .arg( ui->rel_cashier->get_LineEdit()->text() )
                       .arg( "" ),

                       "Ждите идет процесс...",

                       "slot_openShift",

                       QList<QObject*>() << appDef::currentKKT_,

                       QList<QVariant>()
                       << ui->rel_cashier->get_LineEdit()->text()
                       << ui->ledt_cashierInn->text(),

                       retVal

                       );

Check_Result chkRes = Check_Result::fromVariant( retVal );

передаю параметры, получаю результат в retVal.

Хм, то есть обернули вызов слота в диалог? Лучше это реализовать в виде шаблонной функции и вместо имени слота передавать лямбду, тогда отпадает необходимость в QVariant. И лямбду можно гонять на тредпуле, чтобы не фризить UI.

Я бы интерфейс всего этого сделал таким:

template <typename R>
struct OperationResult {
  bool isCanceled;
  R result;
};

class ProgressDialog {
public:
  void log(const QString& line);
  void setProgress(int progress);
  bool isCanceledByUser() const;
};

template <typename R> 
OperationResult<R> runWithProgressDialog(
  const QString& title, 
  int totalSteps, 
  const std::function<R(ProgressDialog& dialog)>& block
);

// пример использования
auto sumResult = runWithProgressDialog("Calc summ", 1000, [](auto& dlg){
  int result = 0;
  for (int i = 0; i < 1000; i++) {
    if (dlg.isCanceledByUser()) return 0;
    result += i;
    dlg.setProgress(i);
    QThread::sleep(100);
  }
  return i;
})

чтобы не фризить UI

QThread::sleep(100); тогда так лучше не делать

Ну это же просто пример блокирующей операции. Если исполняться будет на тредпуле, то фризиться ничего не будет

Если исполняться будет на тредпуле

Стесняюсь спросить, вот у меня один поток в приложении - как у меня будет исполняться на тредпуле или ещё на чем-то?

Хм, то есть обернули вызов слота в диалог?

В принципе да. Но команду можно запускать и вне диалога. Сама команда стартует отложенно по таймеру. Связь между ними диалогом и командой через signal/slot.

Приветствую.

С QVariant не удобно работать. Если хотите по настоящему гибкий диалог, то делайте свой диалог с ноля (c qwidget). Как делать: смотрите исходники qt, там все понятно, например, вот как метод exec в qt реализован.

Вот так у меня своя реализация диалога выглядит:

И НЕ пишите статьи (и заметки) больше об этой фигне, пожалуйста.

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

Перефразирую тогда, если не понятно написал. Не превращайте ресурс в УГ.

Сами подумайте, или забейте в поиске "диалог окно на qt" сколько вылезет ссылок даже на русском. Ну и зачем это здесь?

Не превращайте ресурс в УГ

Ну извините, если задел ваше что-то.
Может кому из новичков все-таки полезно будет.
А "диалог окно на qt" я проверял по интернету и не раз. Тут же не речь о том как вывести диалоговое окно.

Нет, не надо этому учить. Тем более на Хабре. Учить нужно чему-то актуальному, а не тому что безнадёжно устарело. Ваш код - это обёртка над тем что и так есть в Qt. Тем более плохо написанная. Непоянтна вообще конечная цель проекта. Вы узнали что такое сигналы-слоты и что QLabel умеет простейшее форматирование текста - здорово, но зачем это этом писать на Хабре? Об этом можно спокойно прочитать в документации Qt. Зачем вам свой single shot таймер? Чем стандартный не устроил? Зачем вам QVariant? Откройте для себя современный C++ хотя-бы десятилетней давности.

Зачем вам QVariant?

Я третий раз уже объясняю, что мне надо возращать результат выполнения команды как разные объекты, разные варианты классов, структур и т.д. Чего тут не понятного?

Зачем вам свой single shot таймер?

Если вы обратили внимание:

    if ( ! connect ( tmr , SIGNAL(sig_retResult(bool, QVariant)),
                          this , SLOT(slot_retResult(bool, QVariant))) )

таймер возвращает результат в окно (индикации). Этим стандартный не устроил.

Если вам нужен результат асинхронной операции, то для этого есть нормальные подходы. Но я кажется понял что вы хотели.

Что скажете по остальным пунктам?

Если вам нужен результат асинхронной операции , то для этого есть нормальные подходы

Я не уверен, но когда говорится про асинхронную операцию, то всегда создается второй поток.
Я все-таки в своем примере предполагаю, что у меня один поток.

Не обязательно. Есть такое понятие, как цикл обработки сообщений (он же event loop). Вы его запускаете через QApplication::exec. Так вот, если кратко, то гоняется цикл который ожидает определенных событий и дёргает соответствующие обработчики (по таймеру, по событиям от устройств ввода, и пр). Этого уже достаточно для (псевдо) асинхронности. Соответственно сигналы-слоты с таймерами это тоже асинхронность.

Этого уже достаточно для (псевдо) асинхронности

Соглашусь, на timerEvent к примеру можно ожидать чего угодно, не тормозя поток.

С QVariant не удобно работать

Это кому как. Для меня в данном случае это реально панацея от лишних проблем.

KJob вам в помощь

Спасибо конечно. KDE конечно интересно как вариант. Но блин билдить kde исходники пока не готов. На будущее конечно посмотрим и Akonadi в.т.ч. Кстати я под виндой если что.

Билдить весь kde не придется, только kcoreaddons. Он из tier1, зависит только от qt. Ну и от extra-cmake-modules. Под винду собирается.

Ну и от extra-cmake-modules

Тут похоже cmake надо использовать и Qt>=5. В общем я на qmake и Qt4, сами понимаете. Меня больше волнует нет ли в kde развития QTableView и QSqlTableModel. Вот это была бы новость.

Есть. Посмотрите KItemViews

cmake не страшно. Как и современный qt. Все рано придется осваивать, рано или поздно))

KJob вам в помощь

А вы KJob использовали в Qt проектах? Я как-то первый раз об этом слышу.

А в чем проблема? Он на Qt, и достаточно часто используется в самом kde. В KIO, например. Есть ui диалог для него, что бы прогресс показывать, ну и т.п.

Sign up to leave a comment.

Articles