Просмотр сообщений
|
Страниц: 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.proCONFIG+=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 На деле можно выбрать и "-", и написать любые символы, например буквы. Вопрос: как, блин работает этот валидатор?
|
|
|
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 ядра в тех файлах, где нужны данные: Я решил сделать более правильно: надеясь на макрос qApp, я написал вот такой класс: class App : public QGuiApplication { public: App(int &argc, char **argv);
Core core; // Дополнительное поле, содержит ядро }; И создаю приложение уже на основе такого класса: Я думал, что к объекту core смогу обращаться в любом месте программы вот так: Но нет, выяснилось, что макрос qApp возвращает тип QGuiApplication *, а у этого типа, естественно, нет поля core. Вопрос: каким методом можно таскать по всему Qt-коду ссылку на ядро (не передавая его во все методы), и не помещая ядро в глобальную область видимости с последующим extern? PS: qApp->instance тоже не помогает.
|
|
|
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 } }
|
|
|
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. Это что за ограничение такое?
|
|
|
|
|