I'm a beginner in QML.
I have a Loading.qml and a main.qml
I want to display the loading.qml at the application starting, and when all my data are ready, I want to hide the loading.qml and display the main.qml
I want to do that from c++ code
How can I do that ?
Thank you
[UPDATE]
I have tried this
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<MyWindow>("project.mywindow", 1, 0, "MyWindow");
engine.load(QUrl("qrc:/LoadingPage.qml"));
if(engine.rootObjects().isEmpty()) return -1;
// simulate preloading data
std::this_thread::sleep_for(std::chrono::seconds(5));
engine. ? -> switch to another view ?
/*engine.load(QUrl("qrc:/main.qml"));
if(engine.rootObjects().isEmpty()) return -1;*/
return app.exec();
}
My QML
LoadingPage.qml
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 2.0
ApplicationWindow {
id: loading
visible: true
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
title: qsTr("Board")
Loader {
id: pageLoader
}
Component.onCompleted: {
pageLoader.source = "qrc:/main.qml"
loading.visible = false
}
Image {
id: logo
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: 100
height: 100
source: "qrc:/img/download.jpeg"
}
Button {
id: btn
width: 250
height: 250
x: 250
y: 0
onClicked: {
pageLoader.source = "qrc:/main.qml"
loading.visible = false
}
}
}
I want to when my main.qml is ready (when c++ construction of my class MyWindow) is ok, I want to switch to them.
I have an Image to show in my nativescript(with Angular2) app, where I want to make different part of image clickable. For example a human body image and I just want to know which part is clicked by the user.
Is there any way to create image-map just like html???
<CardView height="450" width="350" marginTop="10">
<Image src="res://nerves" height="304" width="114" horizontalAlignment="center" verticalAlignment="center"></Image>
</CardView>
Use the (touch) event binding on your Image element.
Here's an example that prints a console message when you click in the fourth quadrant of the image.
import {
Component
} from '#angular/core';
import * as platform from 'platform';
import {
TouchGestureEventData
} from 'tns-core-modules/ui/gestures';
#Component({
moduleId: module.id,
selector: 'your-component',
template: `
<GridLayout>
<Image src="res://your_image" width="128" height="128"
(touch)="touchImage($event)"
verticalAlignment="middle" horizontalAlignment="center"></Image>
</GridLayout>
`
})
export class YourComponent {
touchImage(event: TouchGestureEventData) {
// This is the density of your screen, so we can divide the measured width/height by it.
const scale: number = platform.screen.mainScreen.scale;
if (event.action === 'down') {
// this is the point that the user just clicked on, expressed as x/y
// values between 0 and 1.
const point = {
y: event.getY() / (event.view.getMeasuredHeight() / scale),
x: event.getX() / (event.view.getMeasuredWidth() / scale)
};
// add custom code to figure out if something significant was "hit"
if (point.x > 0.5 && point.y > 0.5) {
console.log('you clicked on the lower right part of the image.');
}
}
}
}
Using QtQuick, I have a row of 5 images in a repeater. I'd like to implement an animation on hover that's similar to the MacOS dock animation. Here's a picture for reference:
To further break it down, here's what I'm trying to accomplish. These images, on hover, should act as follows:
Hovered images expand
Neighboring images expand, but slightly less
Images don't overlap on expansion
Here is the code I have so far
Row {
spacing: 2
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
id: iconRepeater
model: iconColors()
Image {
source: "icons/" + modelData + ".png"
scale: mouseArea.containsMouse ? 1.5 : 1.0
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: endTimer()
}
Behavior on scale {
PropertyAnimation {
duration: 75
}
}
}
}
}
This expands the image you hover over, but I cannot seem to also effect the neighbors. Any advice is appreciated!
I'd suggest a little more robust solution, where you have control over the zoom factor and the spread and decay of influence:
Column {
Slider {
id: foff
from: 1
to: 5
stepSize: 1
value: 2
snapMode: Slider.SnapAlways
}
Slider {
id: sf
from: 0.5
to: 2.5
stepSize: 0.5
value: 0.5
snapMode: Slider.SnapAlways
}
Slider {
id: dmp
from: 1
to: 5
stepSize: 1
value: 1
snapMode: Slider.SnapAlways
}
}
Row {
id: row
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
anchors.horizontalCenter: parent.horizontalCenter
property int falloff: foff.value // how many adjacent elements are affected
property int current: -1
property real scaleFactor: sf.value // that's how much extra it scales
property real damp: dmp.value // decay of influence
Repeater {
id: iconRepeater
model: 10
Rectangle {
width: 50 * pseudoScale
height: width
anchors.bottom: parent.bottom
color: "red"
border.color: "black"
property real pseudoScale: {
if (row.current == -1) return 1
else {
var diff = Math.abs(index - row.current)
diff = Math.max(0, row.falloff - diff)
var damp = row.falloff - Math.max(1, diff)
var sc = row.scaleFactor
if (damp) sc /= damp * row.damp
diff = diff / row.falloff * sc + 1
return diff
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onContainsMouseChanged: row.current = containsMouse ? index : -1
}
Behavior on pseudoScale {
PropertyAnimation {
duration: 150
}
}
}
}
}
It could be something along the lines of this:
Row {
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
}
Repeater {
id: rep
model: ['red', 'yellow', 'pink', 'green', 'teal', 'orchid', 'blue', 'orange']
property int currentIndex: -10
delegate: Rectangle {
anchors.bottom: parent.bottom
// Calculate the width depending on the currently hovered element
width: (rep.currentIndex === index ? 100 : ((rep.currentIndex - index) === 1 || (rep.currentIndex - index) === -1 ? 80 : 50))
height: width
radius: width / 2
color: modelData
MouseArea {
anchors.fill: parent
hoverEnabled: true
// onEntered/Exited did not react. This will work.
onContainsMouseChanged: {
if (containsMouse) rep.currentIndex = index
else rep.currentIndex = -10 // -10 is safe
}
}
// Makes the movement smooth
Behavior on width {
NumberAnimation {}
}
}
}
}
I tried to put in the necessary explainations as comment in the code.
The only thing that would need some tweeking is, that the dots will be initially shifted when the first resizing happens. Putting it on a flickable and some manual labour for the right position handeling could deal with that. Basically you need to shift the flickable by half the width change (in my case ~ 55 or so) to the left, when the mouse enters, and to the right when it leaves again.
You could also do so with a ListView, most likely, but due to the ever changing estimated size of the background, it might be more challanging to get the positioning right.
I've got a component, a custom keyboard, that takes about 1 second to show/build in React Native.
Is it possible to prebuild this component, say on start up, and have it appear instantly when I need to show it?
The only way to do that is to render it ahead of time. You can easily do this by rendering with zero opacity or translateX out of screen, and make it visible by changing those properties.
Example:
const styles = StyleSheet.create({
invisible: {
opacity: 0,
transform: [
{translateX: -3000}
]
}
})
const MyHeavyComponent = ({isVisible, ...props}) => {
const visiblityStyle = isVisible ? null : styles.invisible;
return (
<View style={visiblityStyle}>
...
</View>
)
}
I'm making an application using React VR. If you don't know React VR, well it's based on React Native with some other components, includes Three.js and other stuff, specific for using WebVR.
I've making a component named NavigateButton. Below is my code:
import React from 'react';
import { AppRegistry, asset, StyleSheet, Pano, Text, View, VrButton, Sphere } from 'react-vr';
export class NavigateButton extends React.Component {
render() {
return (
<VrButton onClick={() => this.onNavigating()}>
<Sphere radius={0.5} widthSegments={10} heightSegments={10} style={{ color: "red" }} />
</VrButton>
);
}
onNavigating() { // This method must throw an event
console.log(this.props.to);
}
};
If the user clicks on the VrButton (this is like a HTML 5 button-tag but for VR with inside it, a sphere), an event must been raised to the place where I call the NavigateButton component. That's on code below:
import React from 'react';
import { AppRegistry, asset, StyleSheet, Pano, Text, View, VrButton, Sphere } from 'react-vr';
import { NavigateButton } from './components/nativateButton.js';
let room = asset('360 LR/inkom_hal.jpg');
export default class MainComp extends React.Component {
render() {
return (
<View>
<Pano source={asset('360 LR/inkom_hal.jpg')} />
<View style={{ transform: [{ translate: [20, 0, 0] }] }}>
<NavigateButton to="garage"></NavigateButton>
<!-- and must been catch here -->
</View>
<View style={{ transform: [{ translate: [-7, 0, -20] }] }}>
<NavigateButton to="woonkamer"></NavigateButton>
<!-- or here -->
</View>
</View>
);
}
}
AppRegistry.registerComponent('MainComp', () => MainComp);
Is it possible to do that? I would something like code below to catch the event:
<NavigateButton to="woonkamer" onNavigate={() => this.change()}></NavigateButton>
I've searched on the internet but nothing found that could help me.
Here is the instruction how to create Sample VR app with React VR prepared by me and my team:
Creating a VR tour for web
The structure of future app’s directory is as follows:
+-node_modules
+-static_assets
+-vr
\-.gitignore
\-.watchmanconfig
\-index.vr.js
\-package.json
\-postinstall.js
\-rn-cli-config.js
The code of a web app would be in the index.vr.js file, while the static_assets directory hosts external resources (images, 3D models). You can learn more on how to get started with React VR project here. The index.vr.js file contains the following:
import React from 'react';
import {
AppRegistry,
asset,
StyleSheet,
Pano,
Text,
View,
}
from 'react-vr';
class TMExample extends React.Component {
render() {
return (
<View>
<Pano source={asset('chess-world.jpg')}/>
<Text
style={{
backgroundColor:'blue',
padding: 0.02,
textAlign:'center',
textAlignVertical:'center',
fontSize: 0.8,
layoutOrigin: [0.5, 0.5],
transform: [{translate: [0, 0, -3]}],
}}>
hello
</Text>
</View>
);
}
};
AppRegistry.registerComponent('TMExample', () => TMExample);
VR components in use
We use React Native packager for code pre-processing, compilation, bundling and asset loading. In render function there are view, pano and text components. Each of these React VR components comes with a style attribute to help control the layout.
To wrap it up, check that the root component gets registered with AppRegistry.registerComponent, which bundles the application and readies it to run. Next step to highlight in our React VR project is compiling 2 main files.
Index.vr.js file
In constructor we’ve indicated the data for VR tour app. These are scene images, buttons to switch between scenes with X-Y-Z coordinates, values for animations. All the images we contain in static_assets folder.
constructor (props) {
super(props);
this.state = {
scenes: [{scene_image: 'initial.jpg', step: 1, navigations: [{step:2, translate: [0.73,-0.15,0.66], rotation: [0,36,0] }] },
{scene_image: 'step1.jpg', step: 2, navigations: [{step:3, translate: [-0.43,-0.01,0.9], rotation: [0,140,0] }]},
{scene_image: 'step2.jpg', step: 3, navigations: [{step:4, translate: [-0.4,0.05,-0.9], rotation: [0,0,0] }]},
{scene_image: 'step3.jpg', step: 4, navigations: [{step:5, translate: [-0.55,-0.03,-0.8], rotation: [0,32,0] }]},
{scene_image: 'step4.jpg', step: 5, navigations: [{step:1, translate: [0.2,-0.03,-1], rotation: [0,20,0] }]}],
current_scene:{},
animationWidth: 0.05,
animationRadius: 50
};
}
Then we’ve changed the output of images linking them to state, previously indicated in constructor.
<View>
<Pano source={asset(this.state.current_scene['scene_image'])}
style={{
transform: [{translate: [0, 0, 0]}]
}}/>
</View>
Navigational buttons
In each scene we’ve placed transition buttons for navigation within a tour, taking data from state. Subscribing to onInput event to convey switching between scenes, binding this to it as well.
<View>
<Pano source={asset(this.state.current_scene['scene_image'])} onInput={this.onPanoInput.bind(this)}
onLoad={this.sceneOnLoad} onLoadEnd={this.sceneOnLoadEnd}
style={{ transform: [{translate: [0, 0, 0]}] }}/>
{this.state.current_scene['navigations'].map(function(item,i){
return <Mesh key={i}
style={{
layoutOrigin: [0.5, 0.5],
transform: [{translate: item['translate']},
{rotateX: item['rotation'][0]},
{rotateY: item['rotation'][1]},
{rotateZ: item['rotation'][2]}]
}}
onInput={ e => that.onNavigationClick(item,e)}>
<VrButton
style={{ width: 0.15,
height:0.15,
borderRadius: 50,
justifyContent: 'center',
alignItems: 'center',
borderStyle: 'solid',
borderColor: '#FFFFFF80',
borderWidth: 0.01
}}>
<VrButton
style={{ width: that.state.animationWidth,
height:that.state.animationWidth,
borderRadius: that.state.animationRadius,
backgroundColor: '#FFFFFFD9'
}}>
</VrButton>
</VrButton>
</Mesh>
})}
</View>
onNavigationClick(item,e){
if(e.nativeEvent.inputEvent.eventType === "mousedown" && e.nativeEvent.inputEvent.button === 0){
var new_scene = this.state.scenes.find(i => i['step'] === item.step);
this.setState({current_scene: new_scene});
postMessage({ type: "sceneChanged"})
}
}
sceneOnLoad(){
postMessage({ type: "sceneLoadStart"})
}
sceneOnLoadEnd(){
postMessage({ type: "sceneLoadEnd"})
}
this.sceneOnLoad = this.sceneOnLoad.bind(this);
this.sceneOnLoadEnd = this.sceneOnLoadEnd.bind(this);
this.onNavigationClick = this.onNavigationClick.bind(this);
Button animation
Below, we’ll display the code for navigation button animations. We’ve built animations on button increase principle, applying conventional requestAnimationFrame.
this.animatePointer = this.animatePointer.bind(this);
animatePointer(){
var delta = this.state.animationWidth + 0.002;
var radius = this.state.animationRadius + 10;
if(delta >= 0.13){
delta = 0.05;
radius = 50;
}
this.setState({animationWidth: delta, animationRadius: radius})
this.frameHandle = requestAnimationFrame(this.animatePointer);
}
componentDidMount(){
this.animatePointer();
}
componentWillUnmount(){
if (this.frameHandle) {
cancelAnimationFrame(this.frameHandle);
this.frameHandle = null;
}
}
In componentWillMount function we’ve indicated the current scene. Then we’ve also subscribed to message event for data exchange with the main thread. We do it this way due to a need to work out a React VR component in a separate thread.
In onMainWindowMessage function we only process one message with newCoordinates key. We’ll elaborate later why we do so. Similarly, we’ve subscribed to onInput event to convey arrow turns.
componentWillMount(){
window.addEventListener('message', this.onMainWindowMessage);
this.setState({current_scene: this.state.scenes[0]})
}
onMainWindowMessage(e){
switch (e.data.type) {
case 'newCoordinates':
var scene_navigation = this.state.current_scene.navigations[0];
this.state.current_scene.navigations[0]['translate'] = [e.data.coordinates.x,e.data.coordinates.y,e.data.coordinates.z]
this.forceUpdate();
break;
default:
return;
}
}
<Pano source={asset(this.state.current_scene['scene_image'])} onInput={this.onPanoInput.bind(this)}
style={{ transform: [{translate: [0, 0, 0]}] }}/>
rotatePointer(nativeEvent){
switch (nativeEvent.keyCode) {
case 38:
this.state.current_scene.navigations[0]['rotation'][1] += 4;
break;
case 39:
this.state.current_scene.navigations[0]['rotation'][0] += 4;
break;
case 40:
this.state.current_scene.navigations[0]['rotation'][2] += 4;
break;
default:
return;
}
this.forceUpdate();
}
Arrow turns are done with ↑→↓ alt keys, for Y-X-Z axes respectively.
See and download the whole index.vr.js file on Github HERE.
Client.js file
Moving further into our React VR example of virtual reality web applications, we’ve added the code below into init function. The goal is processing of ondblclick, onmousewheel and message events, where the latter is in rendering thread for message exchanges. Also, we’ve kept a link to vr and vr.player._camera objects.
window.playerCamera = vr.player._camera;
window.vr = vr;
window.ondblclick= onRendererDoubleClick;
window.onmousewheel = onRendererMouseWheel;
vr.rootView.context.worker.addEventListener('message', onVRMessage);
We’ve introduced the onVRMessage function for zoom returning to default when scenes change. Also, we have added the loader when scene change occurs.
function onVRMessage(e) {
switch (e.data.type) {
case 'sceneChanged':
if (window.playerCamera.zoom != 1) {
window.playerCamera.zoom = 1;
window.playerCamera.updateProjectionMatrix();
}
break;
case 'sceneLoadStart':
document.getElementById('loader').style.display = 'block';
break;
case 'sceneLoadEnd':
document.getElementById('loader').style.display = 'none';
break;
default:
return;
}
}
onRendererDoubleClick function for 3D-coordinates calculation and sending messages to vr component to change arrow coordinates. The get3DPoint function is custom to our web VR application and looks like this:
function onRendererDoubleClick(){
var x = 2 * (event.x / window.innerWidth) - 1;
var y = 1 - 2 * ( event.y / window.innerHeight );
var coordinates = get3DPoint(window.playerCamera, x, y);
vr.rootView.context.worker.postMessage({ type: "newCoordinates", coordinates: coordinates });
}
Switch to mouse wheel
We’ve used the onRendererMouseWheel function for switching zoom to a mouse wheel.
function onRendererMouseWheel(){
if (event.deltaY > 0 ){
if(window.playerCamera.zoom > 1) {
window.playerCamera.zoom -= 0.1;
window.playerCamera.updateProjectionMatrix();
}
}
else {
if(window.playerCamera.zoom < 3) {
window.playerCamera.zoom += 0.1;
window.playerCamera.updateProjectionMatrix();
}
}
}
Exporting coordinates
Then we’ve utilized Three.js to work with 3D-graphics. In this file we’ve only conveyed one function to export screen coordinated to world coordinates.
import * as THREE from 'three';
export function get3DPoint(camera,x,y){
var mousePosition = new THREE.Vector3(x, y, 0.5);
mousePosition.unproject(camera);
var dir = mousePosition.sub(camera.position).normalize();
return dir;
}
See and download the whole client.js file on Github HERE. There’s probably no need to explain how the cameraHelper.js file works, as it is plain simple, and you can download it as well.
Also, if you are interested in a lookalike project estimate or same additional technical details about ReactVR development - you can find some info here: