Russian Qt Forum
Май 05, 2024, 19:16 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: 1 2 [3] 4 5 ... 50
31  Qt / Qt Quick / Не могу спозиционировать Rectangle на весь экран в QML : Июнь 09, 2018, 09:30
Делаю я заготовку виджета. Нужно, чтобы когда он виден, при клике НЕ на его облась, чтобы виджет скрывался.

Я делаю так:

Код:
Window {
    id: picker

    width: 640
    height: 480

    Item {
        id: sdStorageListWidget
        visible: true

        // Рабочая область посередине экрана, в ней будет список sdStorageListView
        width: parent.width/2
        height: parent.height/2
        anchors.verticalCenter: parent.verticalCenter
        anchors.horizontalCenter: parent.horizontalCenter

        // Прямоугольник на весь экран, при нажатии на который виджет скрывается
        // Он нужен, чтобы виджет скрывался всегда при клике не на область списка
        Rectangle {
            anchors.fill: picker.contentItem
            color: "yellow"

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    sdStorageListWidget.visible=false;
                }
            }
        }

        // Зглушка для области списка
        Rectangle {
            id: sdStorageListView
            anchors.fill: sdStorageListWidget
            color: "lightblue"

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log("Click on sdStorageListView");
                }
            }
        }
    }
}

На на строке определения желтого Rectangle появляется ошибка:

Код:
QML Rectangle: Cannot anchor to an item that isn't a parent or sibling.

Что-то я не вкурю, вроде бы всегда можно было позиционироваться относительно любых элементов, которые ближе к корню по иерархии вложения. А тут почему-то говорится что можно позиционироваться только относительно родителя или элементов того же уровня.

Другими словами, желтый прямоугольник можно позиционировать относительно parent, но невозможно относительно parent.parent (оно же picker.contentItem). То есть относительно границ окна не спозиционируешься. Что за бред?
32  Qt / Общие вопросы / Конструкторы QQmlApplicationEngine и QSettings портят таймзону (daylight) : Май 20, 2018, 22:20
Debian Linux 9 Stable 64 bit, Qt 5.10.1

Наткнулся на странное поведение конструктора QQmlApplicationEngine. Минимальный код main.cpp:

Код:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qDebug() << "1ST timezone=" << timezone << " daylight=" << daylight;
    tzset();
    qDebug() << "2ND timezone=" << timezone << " daylight=" << daylight;

    QQmlApplicationEngine engine;

    qDebug() << "3ND timezone=" << timezone << " daylight=" << daylight;

    return app.exec();
}

Результат работы:

Код:
1ST timezone= 0  daylight= 0
2ND timezone= -10800  daylight= 1
3ND timezone= -10800  daylight= 0

То есть, после срабатывания конструктора QQmlApplicationEngine портится daylight.

Я удивился, но работать надо и поэтому попытался обойти это дело так:

Код:
    long saveTimezone=timezone;
    int saveDaylight=daylight;

    QQmlApplicationEngine engine;

    timezone=saveTimezone;
    daylight=saveDaylight;

Сработало, однако в проекте я еще нашел одно место, в котором такое же поведение, после срабатывания конструктора QSettings (но уже в куче). Выглядит так:

Код:
        qDebug() << "CURRENT timezone=" << timezone << " daylight=" << daylight;
        QSettings *config=new QSettings(fileName, QSettings::IniFormat, this);
        qDebug() << "CURRENT timezone=" << timezone << " daylight=" << daylight;

Код:
CURRENT timezone= -10800  daylight= 1
CURRENT timezone= -10800  daylight= 0

В минимальном коде повторить такое не смог.

Вот. Где еще может слетать daylight я ума не приложу, но вероятности такой не исключаю. Проблема в том, что в моем проекте используется легаси библиотека, которая работает с daylight, и из-за этих проблем выдает неправильное время.

Вопросы: что это за ботва такая, почему некоторые Qt классы портят daylight, как это дело гарантированно обойти?

PS: Файл проекта что б быстро собрать минимальный пример (требуется только main.cpp и time.pro):

time.pro

Код:
CONFIG+=c++11
CONFIG+=qml_debug
QT+=gui
QT+=core
QT+=quick
QT+=widgets
SOURCES += main.cpp
DEFINES += QT_DEPRECATED_WARNINGS
33  Qt / Пользовательский интерфейс (GUI) / Что-то не пойму как использовать QValidator совместно с QComboBox : Май 20, 2018, 22:17
Имею такой код:

Код:
#define MINIMUM_ALLOWED_FONT_SIZE 5
#define MAXIMUM_ALLOWED_FONT_SIZE 99

QComboBox fontSize;
...
fontSize.addItem("-",0);
for(int i=MINIMUM_ALLOWED_FONT_SIZE; i<=MAXIMUM_ALLOWED_FONT_SIZE; ++i)
    fontSize.addItem(QString("%1").arg(i),i);

fontSize.setEditable(true);
QValidator *fontsizeValidator = new QIntValidator(MINIMUM_ALLOWED_FONT_SIZE, MAXIMUM_ALLOWED_FONT_SIZE, this);
fontSize.setValidator(fontsizeValidator);


По идее, в таком комбо-боксе не должна быть возможность:

- выбрать первый пункт "-"
- написать что-то отличное от чисел 5-99

На деле можно выбрать и "-", и написать любые символы, например буквы.

Вопрос: как, блин работает этот валидатор?
34  Qt / Qt Quick / Re: На Android стало храниться только одно QML-приложение : Март 01, 2018, 13:59
звучит так, будто идентификатор приписывается один и тот же всем приложениям, во всяком случае в iOS это работает именно так.

Что за идентификатор? Где он устанавливается? Какое значение ему надо задавать?
35  Qt / Qt Quick / На Android стало храниться только одно QML-приложение : Февраль 28, 2018, 18:28
В один прекрасный момент мобильник Huawei Honor 6 без моего согласия молча накатил обновления, снес все программы, и сбросил все настройки включая язык, страну, часовой пояс и т.п. В итоге сейчас стоит Android 6.0 с EMUI 4.0.1.

Вместе с этим изменилось поведение при USB-отладке QML-приложений. Если раньше приложение оставалось на телефоне, и разные QML-приложения имели отдельные значки с дефолтной иконкой «зеленый робот», то теперь на телефоне сохраняется только одно QML-приложение. То есть при запуске абсолютно другого QML-приложения в режиме USB, зачем-то удаляется предыдущее QML-приложение.

Я не могу понять, как с этим бороться. Мне нужно иметь на телефоне несколько QML-приложений, которые будут оставаться на нем и после отладки. Но QML-приложение просто «заменяется» последним отлаживаемым приложением.

Что делать-то, а? Куда копать?
36  Qt / Общие вопросы / Как достучаться до инстанса производного класса QGuiApplication? : Февраль 20, 2018, 18:45
Для того, чтобы не таскать по всему приложению вытаскивание через extern глобальных объектов (всякие синглтоны с наборами конфигурирующих данных):

Код:
extern GlobalParameters globalParameters;
extern FixedParameters fixedParameters;
extern AppConfig appConfig;

... я решил сделать один объект (назовем его ядро) и все эти синглтоны поместить в него как включение.

Но это решение все равно будет требовать extern ядра в тех файлах, где нужны данные:

Код:
extern Core core;

Я решил сделать более правильно: надеясь на макрос qApp, я написал вот такой класс:

Код:
class App : public QGuiApplication
{
public:
    App(int &argc, char **argv);

    Core core; // Дополнительное поле, содержит ядро
};

И создаю приложение уже на основе такого класса:

Код:
App app(argc, argv);

Я думал, что к объекту core смогу обращаться в любом месте программы вот так:

Код:
qApp->core

Но нет, выяснилось, что макрос qApp возвращает тип QGuiApplication *, а у этого типа, естественно, нет поля core.

Вопрос: каким методом можно таскать по всему Qt-коду ссылку на ядро (не передавая его во все методы), и не помещая ядро в глобальную область видимости с последующим extern?

PS: qApp->instance тоже не помогает.
37  Qt / Общие вопросы / Re: Создание Q_PROPERTY : Февраль 13, 2018, 22:22
читал, конечно, просто не понятно каков тогда смысл применения Q_PROPERTY.

Вот небольшая пояснялка по этой теме:

Зачем нужен макрос Q_PROPERTY и как им пользоваться
38  Qt / Qt Quick / Re: Методика запоминания предыдущего значения в QML : Январь 26, 2018, 14:02
Тогда не свойство напрямую менять, а сделать метод-сеттер для свойства и там уже запоминать предыдущее значение.

Да с сеттером (а не с обработчиком) можно. Но тогда надо всю структуру кода менять, который изначально расчитывался на биндинги.

На самом деле, есть возможность даже при биндинге правильно устанавливать предыдущее значение. Обсуждение вот тут:

https://www.linux.org.ru/forum/development/13981618
39  Qt / Qt Quick / Re: Методика запоминания предыдущего значения в QML : Январь 25, 2018, 15:12
Смотри. Код, который находится "выше", задает значение путем установки свойства:

Код:
    RibbonImage {
        targetDigit: timeString.charAt(5)
    }

Он ничего не знает (и не должен знать) про предыдущее значение. Значит, запоминаться предыдущее значение targetDigit должно в самом типе (в нашем случае в RibbonImage).

Отследить изменение свойства targetDigit мы можем с помощью обработчика onTargetDigitChanged(). Но внутри него невозможно сохранить предыдущее значение targetDigit в какое-нибудь еще одно свойство previousDigits. А невозможно потому, что это targetDigit в момент вызова обработчика уже новое. И не из чего получить предыдущее значение, чтобы его запомнить в другом свойстве.
40  Qt / Qt Quick / Методика запоминания предыдущего значения в QML : Январь 25, 2018, 14:14
По причине отсутствия ответов вот в этой теме:

http://www.prog.org.ru/topic_31875_0.html

...хочу разобраться в более общем вопросе. Вопрос звучит так:

Цитировать
Каким образом в языке QML можно организовать запоминание предыдущего значения свойства?

То есть, задача состоит в том, чтобы перед любым изменением свойства запомнить его значение в другое свойство. Проблема в том, что существующий механизм сигналов onИмяСвойстваChanged() испускает сигнал об изменении свойства уже после его изменения. И в этом обработчике невозможно получить предыдущее значение свойства чтобы его запомнить.

Кто что думает? Желательны примеры кода.
41  Qt / Qt Quick / Не работает простая анимация через YAnimator в QML : Январь 24, 2018, 22:48
Делаю счетчик на экране, который должен показывать произвольное число. Для отрисовки цифр используется картинка в виде вертикальной ленты, на которой нанесены цифры 0-9. Цифры на счетчике должны отображаться с анимацией прокрутки.

Для дальнейшей доработки счетчика (нужно будет сделать специальную анимацию для перехода через 0 и 9, т.е. счетчик должен будет уметь прокрутиться от 2 до 8 как 2-1-0-9-8, а не как 2-3-4-5-6-7-8) мне нужно знать с какой предыдущей цифры и на какую целевую цифру он прокручивается.

Целевая цифра хранится как свойство targetDigit. С ней проблем нет: она задается внешним кодом.

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

Код:
previousDigit=targetDigit

... то сразу анимация перестает работать. То есть, числа не «прокручиваются», а просто устанавливаются в нужное значение.

Вот весь код:
Код:
Image {
    id: ribbon
    source: "qrc:/resource/pic/digits/timeDigitRibbon.png"

    // Вертикальные смещения в пикселях
    property double hDelta: -478.0 // Смещение картинки по высоте чтобы при значении 0 картинка нуля была в окошке индикатора
    property double hStep: 53.5    // Шаг между изображением цифр

    // Число, на которое должна переключиться лента
    property int targetDigit: 0

    // Предыдущее число, которое показывала лента
    property int previousDigit: 0


    // Анимация от цифры к цифре
    YAnimator {
        id: directAnimation

        target: ribbon;
        from: hDelta+(previousDigit*hStep);
        to:   hDelta+(targetDigit*hStep);
        duration: 100

        onRunningChanged: {
            if(running==true) {
                console.log( "Start animation digit from: "+previousDigit+" to: "+targetDigit+" (YAnimator from:"+from+" to: "+to+")" )
            }

            if(running==false) {
                previousDigit=targetDigit // <----- Это проблемный код
                console.log( "Stop animation. Set previous: "+previousDigit )
            }
        }

        onFromChanged: {
            console.log("From changed: "+from)
        }

        onToChanged: {
            console.log("To changed: "+to)
        }

    }


    onTargetDigitChanged: {
        console.log(" ")
        console.log("Target digit new: "+targetDigit+" , previous: "+previousDigit)

        directAnimation.start()
    }
}

В логе я вижу следующее:
Код:
Target digit new: 5 , previous: 4
Start animation digit from: 4 to: 5 (YAnimator from:-264 to: -264)
To changed: -210.5
From changed: -210.5
Stop animation. Set previous: 5
 
Target digit new: 6 , previous: 5
Start animation digit from: 5 to: 6 (YAnimator from:-210.5 to: -210.5)
To changed: -157
From changed: -157
Stop animation. Set previous: 6
 
Target digit new: 7 , previous: 6
Start animation digit from: 6 to: 7 (YAnimator from:-157 to: -157)
To changed: -103.5
From changed: -103.5
Stop animation. Set previous: 7

Обратите внимание на длинные строки (Start animation...). Сами цифры там разные: 5 и 4, 6 и 5, 7 и 6. А вот параметры from и to для YAnimator почему-то одинаковые, несмотря на то, что from зависит от previousDigit, а to зависит от targetDigit по одной и той же формуле:

Код:
        from: hDelta+(previousDigit*hStep);
        to:   hDelta+(targetDigit*hStep);

Я грешил на то, что тут как-то некорретно работает property bindings, потому что свойство previousDigit меняется внутри JavaScript:

http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html#creating-property-bindings-from-javascriptv

И я попробовал вместо проблемной строки написать:

Код:
previousDigit=Qt.binding( function() {return targetDigit; } )

Но это никакого эффекта не дало.

Сейчас мне нужно сделать две вещи:
- научиться запоминать previousDigit. Если текущий способ не подходит, может быть есть какой-то другой.
- научиться запускать анимацию с использованием значений previousDigit и targetDigit. Как видно, текущий способ некорректно выставляет свойства from и to.

Вот. Кто может подсказать как обойти эти два затыка?
42  Qt / Qt Quick / Re: Связывание свойств в QML: почему не работает? : Январь 23, 2018, 13:45
Отвечаю сам себе. Оказывается, механизм property binding не распространяется на свойства, которые получают свои значения из JavaScript функций. Для того, чтобы заработал property binding, надо обернуть JavScript-функцию конструкцией Qt.binding( ... ), как на примере:

Код:
Keys.onSpacePressed: {
        height = Qt.binding(function() { return width * 3 })
    }

Здесь видно, что оборачивается безымянная функция, которая прописана прямо на месте своего использования.

Как обернуть именованную функцию, в документации не сказано, надо разбираться дальше.
43  Qt / Qt Quick / Связывание свойств в QML: почему не работает? : Январь 18, 2018, 13:42
Делаю я сейчас самодельный тип для отображения компаса. Компас состоит из корпуса и стрелки. Для корпуса и стрелки подготовлены PNG-рисунки.

Размер корпуса на экране зависит от размера области, в которую он вставляется (кстати, эта область гарантированно квадратная):

Код:
Image {
    id: compassCase
    width: parent.width*0.8
    height: parent.height*0.8
    source: "qrc:/resource/pic/compassIndicator/compassCase.png"

Таким образом, корпус компаса приобретает некий масштаб. И его нужно использовать при отрисовке стрелки, чтобы масштаб стрелки соответствовал масштабу компаса. Для вычисления и запоминания масштаба я создаю свойство elementScale:

Код:
    property int elementScale: mathScale(sourceSize.width, width)
...
    function mathScale( sourceWidth, screenWidth ) {
        var scale=screenWidth/sourceWidth

        console.log("Compass scale "+scale);

        return scale
    }

В логе я вижу такие значения:

Код:
qml: Compass scale NaN
qml: Compass scale NaN
qml: Compass scale 0
qml: Compass scale 0.617611580217129

И это свойство я пытаюсь применить к стрелке:

Код:
    Image {
        id: arrow
        source: "qrc:/resource/pic/compassIndicator/arrow.png"
        scale: compassCase.elementScale
    }

Но оно, как я выяснил, на момент использования содержит нуливое значение, и стрелка приобретает нуливой масштаб и становится нуливого размера. А выяснил я это так:

Код:
    scale: printScale(compassCase.elementScale)
...
    function printScale( scale ) {
        console.log("Arrow scale "+scale);
        return scale
    }

А в логе получается вот такое:

Код:
qml: Compass scale NaN
qml: Arrow scale -2147483648
qml: Compass scale NaN
qml: Compass scale 0
qml: Arrow scale 0
qml: Compass scale 0.617611580217129

Я не понимаю, почему после последнего изменения масштаба компаса (значение 0.61) не пересчитывается значение масштаба для стрелки? Ведь на эти значения (compassCase.elementScale и scale для arrow) вроде как распространяется связывание свойств (property binding)?

Вот, для понимания, весь код:

Код:
Image {
    id: compassCase
    width: parent.width*0.8
    height: parent.height*0.8
    source: "qrc:/resource/pic/compassIndicator/compassCase.png"

    // Масштаб для всех подчиненных элементов, на основе масштаба корпуса компаса
    property int elementScale: mathScale(sourceSize.width, width)

    Image {
        id: arrow
        source: "qrc:/resource/pic/compassIndicator/arrow.png"
        scale: printScale(compassCase.elementScale)
    }

    function mathScale( sourceWidth, screenWidth ) {
        var scale=screenWidth/sourceWidth

        console.log("Compass scale "+scale);

        return scale
    }

    function printScale( scale ) {
        console.log("Arrow scale "+scale);
        return scale
    }
}
44  Qt / Qt Quick / Re: QML: Почему нельзя обратиться к типу Window по id? : Январь 10, 2018, 19:21
В общем, разобрался:

Особенности иерархии при использовании типов Window и ApplicationWindow
45  Qt / Qt Quick / QML: Почему нельзя обратиться к типу Window по id? : Январь 10, 2018, 10:47
Есть у меня вот такой пример с прямоугольником:

Код:
    Rectangle {
         id: page
         width: 640
         height: 480
         color: "lightgray"

         Text {
             text: "Hello world!"
             anchors.horizontalCenter: page.horizontalCenter
         }
     }

Здесь видно, что внутри Text происходит обращение к вышестоящему Rectangle по id page. И происходит центрирование текста относительно прямоугольника. Все работает правильно.

Теперь делаем то же самое с Window:

Код:
Window {
    id: content
    visible: true
    width: 640
    height: 480

    Text {
        text: "Hello world!"
        anchors.horizontalCenter: content.horizontalCenter
    }
}

И видим, что обращение по id content не работает. Центрирования не происходит.

А если вместо id написать parent, то центрирование работает:

Код:
Window {
    id: content
    visible: true
    width: 640
    height: 480

    Text {
        text: "Hello world!"
        anchors.horizontalCenter: parent.horizontalCenter
    }
}

То есть, по каким-то причинам для типа Window невозможно обращение через id.

Это что за ограничение такое?
Страниц: 1 2 [3] 4 5 ... 50

Страница сгенерирована за 0.063 секунд. Запросов: 23.