LINUX.ORG.RU

Сообщения Nikci12

 

Как оптимизировать отрисовку сцены?

Форум — Development

Добрый день!

У меня есть сцена, которая активно перерисовывается при взаимодействии.

Индексация сцены отключена.

Когда на ней становится много объектов, она начинает перерисовывать чуть медленней. Вроде всё логично, но есть одно НО

Я делал сборку под Linux на компиляторе GCC на версии Qt5.12.11 Под Windows собирал на MSVC17 64bit

И сборка на Линукс (GCC) работает гораздо быстрей, чем под Windows(MSVC17)…

Начал делать замеры скорости выполнения функций и наткнулся на странность:

Функция:

/* Функция перерисования вертикальных осей */
void Viewer::RedrawTimeAxes()
{
    QTime timer;
    timer.start();
    deleteItemsGroup(grTimeAxes);
    int stepInAxis = projectGID->timeAxes.stepAxis;
    // Берем из настроек шаг.
    int stepMinutes = cofigGID->stepMinets();
    //Скролл по минуте
    QDateTime tempDateTime = cofigGID->startDateTime();
//    qDebug() << ">>>>>>[Ведем просмотр даты] " << cofigGID->startDateTime() << "]";
    // Определяем минуту даты.
    int currentMinute = tempDateTime.time().minute();
    // Определяем час даты
    int currentHour = tempDateTime.time().hour();
    /* Находим след. интервал кратный шагу. Прим. Для шага 5: 44 минуты(след 45), 02 минуты(след 05) итд */
    //(Прим: currentMinute = 47, stepMinutes = 5, 47 - (47%5) + 5 = 50
    int nextMinuteStep =  currentMinute - (currentMinute % stepMinutes) + stepMinutes;
    // Находим недостаток минут до след. шага. (Прим: stepMinutes=5, currentMinute=47 => nextMinuteStep = 50)
    //                                         (Прим: stepMinutes=15,currentMinute=47 => nextMinuteStep = 0)
    int offsetMinutes = nextMinuteStep - currentMinute;
    // Переводим отступ в пиксели
    qreal offsetInPixels = (qreal(stepInAxis) / stepMinutes) * offsetMinutes;
//    qDebug() << "StepInAxis = " << stepInAxis << "...StepMinutes= " << stepMinutes << "...offsetMinutes = " << offsetMinutes;
    // Зануляем количество видимых осей
    projectGID->timeAxes.countAxes = 0;
    qDebug() << "Расчеты произведены за " << timer.elapsed() << " мс";
    QTime timer2;
    timer2.start();
    qDebug() << "[НАЧАЛО ОТРИСОВКИ ОСЕЙ]";
    qreal nStep = offsetInPixels;
    while( nStep < scene()->width() )
    {
        /* определяем значение отрисовываемой минуты */
        int currentMinuteDraw = nextMinuteStep % SECONDS_IN_MINUTE;
        /* определяем значение отрисовываемого часа. */
        int currentHourDraw = (currentHour + (nextMinuteStep / SECONDS_IN_MINUTE)) % HOURS_IN_DAY;
        qreal xPos = nStep;
//        int yPos = projectGID->rcGidPlan.height() - fmsGid->height() - m_offsetTimeScaleScene;

        /* Проверяем если отрисовочная минута == 0, значит отрисовываем час */
        if (currentMinuteDraw == 0) {
            QTime timerHour;
            timerHour.start();
            DrawVerticalAxeHour(xPos, currentHourDraw);
            qDebug() << "Часовая ось отрисовалась за : " << timerHour.elapsed() << " мс";
        } else {
            QTime timerMinute;
            timerMinute.start();
            DrawVerticalAxeMinute(xPos, currentMinuteDraw);
            qDebug() << "Минутная ось отрисована за : " << timerMinute.elapsed() << " мс";
        }

        /*Отрисовываем текущую дату*/
        QTime timerDate;
        timerDate.start();
        DrawWatchingDate();
        qDebug() << "Время отрисовки даты: " << timerDate.elapsed() << " мс";
        /* Переводим nextTimeStep дальше по шагу */
        nextMinuteStep = nextMinuteStep + cofigGID->stepMinets();
        // Пополняем количество нарисованных осей
        projectGID->timeAxes.countAxes++;
        nStep += projectGID->timeAxes.stepAxis;
    }
    qDebug() << "Цикл отрисовки произведен за : " << timer2.elapsed() << " мс";
    // Расчитываем последнюю дату просмотра
    lastWatchingTime = cofigGID->startDateTime().addSecs(cofigGID->secondsInPixel(projectGID->timeAxes.stepAxis) * scene()->width() + SECONDS_IN_MINUTE);
    // Зануляем секунды
    lastWatchingTime.setTime(QTime(lastWatchingTime.time().hour(), lastWatchingTime.time().minute()));
//    qDebug() << "<<<[APPROXIMATE END WATCH DATA] " << lastWatchingTime;
    /* отрисовка горизональной линии разделяющую сцену шкалы времени от сцены санций и сетки ГИД */
    const int yPosSeparator = projectGID->rcGidPlan.height() - m_offsetTimeScaleScene - fmsGid->height()*2;
    grTimeAxes->addToGroup(scenePlan->addLine(0, yPosSeparator, scenePlan->width() - 1, yPosSeparator, QPen(palette().color(foregroundRole()))));
    qDebug() << "=====КОЛИЧЕСТВО ЭЛЕМЕНТОВ======" << scene()->items().count();
    qDebug() << "Полный цикл отрисовки : " << timer.elapsed() << " мс";
}

Функция DrawVerticalAxeMinute

/* Отрисовка вертикальной МИНУТНОЙ ОСИ */
void Viewer::DrawVerticalAxeMinute(qreal xPos, int minuteDraw)
{
    QFont font(cofigGID->font);
    /* Вычисляем высоту для минут */
    int yPos = projectGID->rcGidPlan.height() - fmsGid->height()*2 - m_offsetTimeScaleScene;
    QTime timerAddGroup;
    timerAddGroup.start();
    auto line = scenePlan->addLine(xPos, 0, xPos, yPos,
                                   cofigGID->lineScaleStep.pen());
    qDebug() << ">[МИНУТНЫЕ ОСИ]ДОБАВЛЯЕМ ЛИНИЮ НА СЦЕНУ " << timerAddGroup.elapsed() << " мс";
    timerAddGroup.restart();
    grTimeAxes->addToGroup(line);
    qDebug() << "<[МИНУТНЫЕ ОСИ]ДОБАВЛЕНО В ГРУППУ " << timerAddGroup.elapsed() << " мс";
    font.setBold(false);
    timerAddGroup.restart();
    auto text = scenePlan->drawText(
                QString("%0").arg(minuteDraw),
                /*  Выравнивание, если у нас отрисовываемая минута < 10 (для одного числа съезжает чуть-чуть, поэтому делим на 4, если >10, то делим на 2)*/
                /*xPos*/(minuteDraw < 10) ? (xPos - fmsGid->height() / 4) : (xPos - fmsGid->height() / 2),
                                       yPos, font, cofigGID->clrFont.color());
    qDebug() << ">>[Минутные ОСИ]ДОБАВЛЕН ТЕКСТ" << timerAddGroup.elapsed() << " мс";
    timerAddGroup.restart();
    grTimeAxes->addToGroup(text);
    qDebug() << ">>[МИНУТНЫЕ ОСИ]Добавление в группу2 происходило " << timerAddGroup.elapsed() << " мс";
}

В windows Начинает работать дольше на функции, которая первая добавит элемент на сцену/добавит в графическую группу( и будет долго работать всего один раз) следующие разы, уже отрабатывает как на linux..

А на Linux быстро и сразу(причем даже объекты гораздо большие, отрисовывает гораздо быстрей)…

Ссылка на логи(визуально глянуть) : https://postimg.cc/gallery/D1VRCpt

Логи физические: https://dropmefiles.com/IF3TU

 , ,

Nikci12
()

Как вывести на печать 2 QGraphicsScene?

Форум — Development

Здравствуйте!

У меня есть две QGraphicsView ( у каждой своя сцена ).

Выглядит это примерно так: https://postimg.cc/TyFbvvYZ

По сути мне нужно напечатать QGraphicsScene слева, совмещенную с QGraphicsScene справа

Как мне совместить эти две сцены на печать(при условии что они имеют одинаковую высоту всегда и синхронизированы между собой по вертикальному скроллингу)?

 , , ,

Nikci12
()

Как прервать открытия файла в Qt?

Форум — Development

Здравствуйте! Разрабатываю ПО для Windows и Linux и столкнулся с проблемой, что если в windows QFile-ом открыть удаленный файл(если доступа нет), то открывается он очень долго(секунд 15) и в конце концов возвращает false, в Linux аналогично.

Код функции примерно таков:


void function(const& QString filename, const& QString secondFilename)
{
    QFile file(filename); // пример windows: filename="//192.168.0.1/folder/file.txt
                          // пример linux: filename="/mnt/192.168.0.1/file.txt(монтирую сразу на папку folder)
    if (file.open()) { // На этом моменте и зависает...(если доступа по локалке нет)
       doSomeWork();
    } else {
      QFile reserveFile(secondFilename); // Если файл с первым именем не открылся, пробуем открыть резервный файл(тоже лежащий удаленно). Прим: //192.168.1.1/folder/file.txt или аналогично для линуксы
      if (reserveFile.open()) { // Здесь тоже есть возможность зависания
           doSomeWork();
      }
      reserveFile.close();
    }
    file.close();
}

Выводил в отдельный поток при этом ожидая в основном потоке 500 мс через QThread::msleep(500); потом убивал поток через QThread::terminate() и делал QThread::wait() но ожидание тоже долгое. Иногда даже дольше чем открывать файл.

Подскажите как верно реализовать отмену функции открытия файла( и не дожидаться окончания её работы ) если прошел некоторый timeout предположим в 500 мс?

 , , ,

Nikci12
()

RSS подписка на новые темы