Recently I tried kivy, but I meet several problems. Thanks for help.
First, my kivy program always rotates screen when running on android. Usually the status bar on android is on the top, when I run kivy it goes to the right side.
Screen rotation is enabled on my android, but when I rotate my phone, the direction of kivy program doesn't change.
And I also try to rotate window by Window.rotation = 90, but the position of status bar didn't change.
The program is very simple:
main.py:
from kivy.app import App
from kivy.uix.widget import Widget
class PongGame(Widget):
pass
class PongApp(App):
def build(self):
return PongGame()
if __name__ == '__main__':
PongApp().run()
pong.kv:
<PongGame>:
canvas:
Rectangle:
pos: self.center_x - 5, 0
size: 10, self.height
Label:
font_size: 70
center_x: root.width / 4
top: root.top - 50
text: "0"
Label:
font_size: 70
center_x: root.width * 3 / 4
top: root.top - 50
text: "0"
Thanks.
First, my kivy program always rotates screen when running on android. Usually the status bar on android is on the top, when I run kivy it goes to the right side.
This is an option in the buildozer.spec, just change the orientation line to orientation = all. You can also read the comments on all the other lines to see the other options.
You can also set many more orientation options (including e.g. optionally obeying the user's system settings etc) by calling the android api directly with pyjnius. I have some example code for this here. Something similar will probably go in plyer.
If you're using python-for-android directly, the orientation option is one of the command line arguments you can pass to build.py. I don't remember offhand but you can check the documentation - though I recommend using buildozer anyway.
Related
I am trying to make a data plotter using matplotlib on a Kivy-based GUI. I have 48 polynoms in same graph as Line2D. Some of them can overlap at many points. Thus I need to have an inset axes to present a zoom option. I am updating a position array with on_touch_move callback and redrawing graph in a scheduled callback using Clock.schedule_interval. The problem is updating inset plot is very slow. It takes 70ms on Windows which is negligible but in android it is very laggy. A reference snippet is below.
`
def plot_graph(self):
self.fig, self.ax = plotter.subplots(1, 1)
self.axin = inset_axes(self.ax, width=4, height=2)
self.fig.tight_layout()
for data in data_set:
line, = self.ax.plot(data)
self.axin.plot(data)
self.add_widget(FigureCanvasKivyAgg(self.fig))
Clock.schedule_interval(self.update_inset, .1) # .2 does not work also
mark_inset(self.ax, self.axin, loc1=1, loc2=3)
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
point = self.ax.transData.inverted().transform(touch.pos)
self.inset_points = point[0] - 2.5, point[0] + 2.5, point[1] - .25, point[1] + .25
def update_inset(self, *args):
if len(self.inset_points) == 4: # To avoid crashes before graph drawn
self.axin.set_xlim(self.inset_points[0], self.inset_points[1])
self.axin.set_ylim(self.inset_points[2], self.inset_points[3])
self.axin.figure.canvas.draw()
`
I have tried funcAnimation but did not help, since it is not compatible with Kivy. Scheduling seems the best way to update it, but it must be faster, at least for android.
I am trying to use this photo camera plugin cordova-plugin-camera-preview in an HTML hybrid application and it works, but I can not place the controls on the camera layer while I focus. However, they appear above the layer when I take the photo and the camera shows the preview. Does anyone know if there is any configuration that can make the buttons appear on the camera layer?
Finally I found the solution in this line in js/index.js
var app = {
startCameraAbove: function(){
CameraPreview.show();
CameraPreview.startCamera({x: 0, y: 0, width: window.screen.width, height:
window.screen.height, camera: "back", toBack: true, previewDrag: false, tapPhoto: true});
},
At the beginning of the js/index.js script we must place these values in toBack:true to keep the camera back completely (be careful, the HTML background can cover it, I recommend put background: transparent in CSS), it is also recommended change previewDrag: false to avoid unveiling the background.
While testing out an application on Android I noticed something funky going on. A double click event handler has been triggering without any double clicks occurring on that particular item.
Trying to isolate the issue I discovered that pretty much every chain of clicks rapid as a double click on regardless what two objects would cause the second click on the second object to register as a double click, when in fact it is just a single click.
Below is an example consisting of a row of 3 randomly colored rectangles, each one with a mouse area inside of it. The double click of each mouse area is rigged to set the parent rectangle's color to a different random color. Clicking rapidly two different rectangles under android triggers a double click and a color change for the second. This does not happen on Windows or Ubuntu Linux.
Window {
id: main
visible: true
width: 400
height: 400
title: qsTr("Hello World")
Row {
Rectangle {
width: main.width * .33
height: main.height
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
border.width: 2
MouseArea {
anchors.fill: parent
onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
Rectangle {
width: main.width * .33
height: main.height
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
border.width: 2
MouseArea {
anchors.fill: parent
onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
Rectangle {
width: main.width * .33
height: main.height
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
border.width: 2
MouseArea {
anchors.fill: parent
onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
}
}
It looks as if the "previous click" or whatever property that's supposed to be used to detect double clicks is shared between different mouse areas instead of being per mouse area. The issue manifests in both Qt 5.7 and 5.7.1.
It definitely looks like my 10th discovered Qt bug this year, but I still feel like asking on the odd chance someone knows what's going on and how to fix it, because I need this fixed, and the Qt bugreport process is not speedy. So any ideas are more than welcome.
Until there is a better answer with an actual solution, it may be useful to know that it is possible to somewhat mitigate the devastating effect this issue has on user experience by reducing the global interval for double click detection.
By default it is the rather lethargic 500 msec. I found out that by reducing it to 250 msec helps to avoid over 90% of the incorrect double clicks:
QGuiApplication app(argc, argv);
app.styleHints()->setMouseDoubleClickInterval(250);
Additionally, there is a quick and hacky qml-only way to create a "fixed" copy of MouseArea:
// MArea.qml
Item {
id: main
property alias mouseX : ma.mouseX
property alias mouseY : ma.mouseY
property alias acceptedButtons: ma.acceptedButtons
// etc aliases
signal clicked(var mouse)
signal doubleClicked(var mouse)
// etc signals, function accessors
MouseArea {
id: ma
property real lClick : 0
anchors.fill: parent
onClicked: {
var nc = Date.now()
if ((nc - lClick) < 500) main.doubleClicked(mouse)
else main.clicked(mouse)
lClick = nc
}
}
}
This one actually works as intended and can be made almost entirely "plug and play" compatible with the original one.
I'm using Nativescript 1.6 and this component https://github.com/bradmartin/nativescript-floatingactionbutton
I would like to have some nice "material design effect" when you click on this button and then navigate to another page. It's a bit hacky but it does the job and looks quite nice (i probably should use fragment transitions with shared elements when i was in native Android world, but im not)
My current attempt:
XML:
<FAB:fab tap="tap"
loaded="buttonLoaded"
row="1"
icon="res://ic_add_white_24dp"
rippleColor="#f1f1f1"
class="fab-button" />
JS:
fabButton.icon = ""; // Error! ResourceNotFoundException
fabButton.animate({
scale: { x: 20, y: 20 },
translate: { x: -200, y: -200 },
duration: 300
}).then(function(){
navigation.goToDetailPage();
fabButton.animate({ // reset button to original state
scale: { x: 1, y: 1 },
translate: { x: 0, y: 0 },
delay: 100,
duration: 0
});
});
2 questions:
How can i remove the icon, just for a nicer effect? "", {}, null are not allowed, should i really create a transparent png for this?
Is there a better way to restore/reset element after an animation?
If the exception is ResourceNotFoundException that looks like a native exception thrown so it doesn't look like you'll be able to set a null value. Your best option is probably an empty .png. I suppose the plugin could check for a null value and bypass the native exception but for now that's not the case. You could make a PR with this feature if you wanted.
As for resetting an element to its original state, what you are doing is what I would do. I don't think there would be a "better" way because once you've changed the state with the initial animation, the native setTranslateX/Y and other methods to run the animation have changed the items location/position/color, etc. So what you are doing is probably the best approach.
I'd like to see this animation if you don't mind, looks like something other devs might want :) Maybe record a .gif and attach here for others to see as a reference. If you don't have a tool to record a .gif here is what I use: http://www.cockos.com/licecap/ when I record from the emulators.
Hope this helps some.
I was wondering if someone could give me a detailed explanation on how to run a game/app developed using Pygame on an Android phone. I recently finished programming PacMan and it works perfectly on my computer, but I think it would be awesome if I could get it running on my phone. I tried following the instructions at http://pygame.renpy.org/android-packaging.html, but every time i run "import android" on the IDLE I get an error saying it did not find the module. Could someone clearly explain how to set up the android module?
Also, in my program I used code such as if (event.key == K_UP or event.key == K_w): direction = UP. However there are no arrow keys on a phone. What code would I need to use to see if the user swiped the screen with their fingers from up -> down or left -> right, etc.
Any help would be great. Thanks <3
There is a pyGame subset for android. However this requires special reworking and changing the program. Hopefully it will not be to hard.
http://pygame.renpy.org/writing.html
http://pygame.renpy.org/index.html
However about your second question i am unable to awnser because I am Not yet experienced enough.
i think the pygame subset for android would be good but i dont trust its functionality, i use kivy as its cross platform
and if you ever decide to use the pygame subset for android your touch of flips on screen of an android device would be your mouse movement on the desktop so i ma saying treat the touch as the mouse good luck
There are some pretty good answers for your first part already so I won't answer that. (I came here looking into what to use for it too!)
However the second part of your question should be a lot easier.
Have a mouse object that on a mouse down event will save the coordinates of the touch to an MX and MY variable
Then when the mouse up event is triggered takes the new coordinates and calculates a vector using the MX and MY and this new point ie. The distance and angle of the swipe. Use trigonometry or the math module for the angle (research arctan2).
You can then use this in an if, elif, else to determine what quadrant the angle was and the distance to determine whether the swipe was valid if it's greater than a certain value.
I'm on mobile so unfortunately I can't give an example, however I'm certain you're apt to work out the solution with this guidance.
For your second question, there is an answer in another website.
https://amp.reddit.com/r/Python/comments/2ak14j/made_my_first_android_app_in_under_5_hours_using/
it says You can try code like this
if android:
android.map_key(android.KEYCODE_BACK, pygame.K_ESCAPE)
I hope it will help you.
I've runned pygame for android!!!!
Firstly, I'm debugged app using saving error to file.
I got error that on android it can be runned only under fullscreen.
I've created small app and it working:
import sys, os
andr = None
try:
import android
andr = True
except ImportError:
andr = False
try:
import pygame
import sys
import pygame
import random
import time
from pygame.locals import *
pygame.init()
fps = 1 / 3
width, height = 640, 480
screen = pygame.display.set_mode((width, height), FULLSCREEN if andr else 0)
width, height = pygame.display.get_surface().get_size()
while True:
screen.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.flip()
time.sleep(fps)
except Exception as e:
open('error.txt', 'w').write(str(e))
Screenshot: https://i.stack.imgur.com/4qXPe.png
requirements in spec file:
requirements = python3,pygame
APK File size is only 12 MB!
pygame.event has multiple touch-screen events. Here are some useful ones:
FINGERMOTION: touch_id, finger_id, x, y, dx, dy
FINGERDOWN: touch_id, finger_id, x, y, dx, dy
FINGERUP: touch_id, finger_id, x, y, dx, dy
MULTIGESTURE: touch_id, x, y, pinched, rotated, num_fingers