qt - Dynamically change Images when current locale changed -
the interface of simple video player, consists of video , image items, blended blend qtgraphicaleffects. image has associated mousearea , translucent graphical buttons "hardcoded" text in english. default images provided qquickimageprovider following locations:
import qtqml 2.2 import qtquick 2.9 import qtmultimedia 5.9 import qtgraphicaleffects 1.0 blend { id: blender mode: "normal" property alias playbackstate: video.playbackstate onvisiblechanged: { if (!visible) { video.playlist.clear() } } source: video { id: video visible: false width: blender.width height: blender.height fillmode: videooutput.stretch playlist: playlist { onerrorchanged: { if (error() !== playlist.noerror) { console.log("error: %1 (%2)".arg(error()).arg(errorstring())) video.stop() } } function nextinloop() { currentindex = (currentindex + itemcount + 1) % itemcount } function previousinloop() { currentindex = (currentindex + itemcount - 1) % itemcount } } connections { target: videoplayersingleton onsetplaylist: { if (video.playlist.clear()) { if (video.playlist.additems(playlist)) { if (index < 0) { video.playlist.playbackmode = playlist.random } else { video.playlist.currentindex = index video.playlist.playbackmode = playlist.sequential } video.play() } } } } autoplay: true loops: mediaplayer.infinite } foregroundsource: image { visible: false width: blender.width height: blender.height sourcesize: qt.size(width, height) source: { switch (playbackstate) { case mediaplayer.playingstate : return "image://videoplayer/pause" case mediaplayer.pausedstate : return "image://videoplayer/play" case mediaplayer.stoppedstate : return "image://videoplayer/logo" } } smooth: true } mousearea { anchors.fill: parent readonly property rect previousbutton: qt.rect((130 - 40) / 1920, (505 - 40) / 1080, 80 / 1920, 80 / 1080) readonly property rect nextbutton: qt.rect((1800 - 40) / 1920, (505 - 40) / 1080, 80 / 1920, 80 / 1080) readonly property rect playpausebutton: qt.rect((950 - 40) / 1920, (980 - 40) / 1080, 80 / 1920, 80 / 1080) readonly property rect backtocatalogbutton: qt.rect((1510 - 40) / 1920, (980 - 40) / 1080, 80 / 1920, 80 / 1080) readonly property rect opencollectionbutton: qt.rect((1710 - 40) / 1920, (980 - 40) / 1080, 80 / 1920, 80 / 1080) onclicked: { var hit = qt.point(mouse.x / width, mouse.y / height) if (videoplayersingleton.contains(previousbutton, hit)) { video.playlist.previousinloop() } else if (videoplayersingleton.contains(nextbutton, hit)) { video.playlist.nextinloop() } else if (videoplayersingleton.contains(playpausebutton, hit)) { if (playbackstate === mediaplayer.playingstate) { video.pause() } else { video.play() } } else if (videoplayersingleton.contains(backtocatalogbutton, hit)) { videoplayersingleton.backtocatalog(video.playlist.currentindex) } else if (videoplayersingleton.contains(opencollectionbutton, hit)) { videoplayersingleton.opencollection(video.playlist.currentindex) } } } } there corresponding images in +ru_ru/ subfolder resources.
c++ qobject singletone global context may have signal void languagechanged(qlocale locale);, emitted, when qtranslators replaced in qcoreapplication::removetranslator/installtranslator each of loaded resource.
// i18n.hpp: #pragma once #include <qtcore> q_declare_logging_category(i18ncategory) #ifndef project_default_locale #define project_default_locale "ru_ru" #endif class internationalization : public qobject { q_object static qmutex mutex; static internationalization * self; explicit internationalization(qstring projectname = qstringliteral(project_name)); public : static internationalization * instance() { q_assert(qapp); qmutexlocker lock{&mutex}; if (!self) { self = ::new internationalization; } return self; } void setdependencies(qstringlist dependencies); public q_slots : void load(qlocale locale = qstringliteral(project_default_locale)); q_signals : void abouttolanguagechanged(); void languagechanged(qlocale locale); private : qstringlist translations; qlist< qpointer< qtranslator > > translators; }; #define i18n internationalization::instance() // i18n.cpp: #include "i18n.hpp" q_logging_category(i18ncategory, "internationalization") qmutex internationalization::mutex; internationalization * internationalization::self = q_nullptr; internationalization::internationalization(qstring projectname) : qobject{qapp} { translations.prepend(projectname); translations.prepend(project_name); } void internationalization::setdependencies(qstringlist dependencies) { translations << dependencies; } void internationalization::load(qlocale locale) { // get_target_property(qt_qmake_executable qt5::qmake imported_location) // qmake -query qt_install_translations q_assert(!(translators.size() > translations.size())); while (translators.size() < translations.size()) { translators << ::new qtranslator{qapp}; } q_emit abouttolanguagechanged(); qlocale::setdefault(locale); qmutablelistiterator translator{translators}; (const auto translation : translations) { q_assert(translator.hasnext()); const auto t = translator.next(); if (!qcoreapplication::removetranslator(t)) { if (!t->isempty()) { qcdebug(i18ncategory).noquote() << tr("unable remove translation project %1") .arg(translation); } } if (t->load(locale, translation, ".", ":/i18n")) { if (!qcoreapplication::installtranslator(t)) { qcdebug(i18ncategory).noquote() << tr("unable install translation %1 locale project %2") .arg(locale.name(), translation); } } else { qcdebug(i18ncategory).noquote() << tr("unable load translation %1 locale project %2") .arg(locale.name(), translation); } } q_emit languagechanged(locale); } i want change locations of images on signal emitted along locale changing. possible change selected files @ runtime (i.e. w/o recreating of parent item, contains videoplayer)?
connected question: affected file selectors first: qimagereader's filepaths used internally qquickimageprovider or source: of quick's image? latter derived first. or maybe both?
Comments
Post a Comment