I have created a simple kivy app which is successfully running on windows. It takes barcode of products as input and proceed further. I have designed my own keypad for my application + It takes input from Barcode Scanner as well (Scanned barcode is being placed in focused TextInput). For this, I have set
Config.set('kivy', 'keyboard_mode', 'system')
which works perfectly fine.
Now, I want to run this app on android. On android, when a TextInput get's focus the android's keyboard becomes visible, which I don't want. I set TextInput property 'keyboard_mode' to 'managed' for this but it stops putting scanned barcode (from Barcode Scanner) in TextInput (as system keyboard will not be requested now).
What I want, hide the keyboard but it remain binded with focused TextInput, to access input from Barcode Scanner. I am stuck here, any help will be highly appreciated.
I am using: kivy==2.0.0, python==3.7.9 and buildozer to package application for android.
I have a few ideas but I first want to double check that you've put the Config.set('kivy', 'keyboard_mode', 'system') statement in the right place.
This needs to come before everything, i.e. the first two lines of your your main.py file should look like this:
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'system')
from kivy.app import App
from kivy.core.window import Window
# etc.
The reason I ask this, is because writing Config.set() after importing App has no effect. On your computer I believe the default keyboard_mode is '' which is to simply choose the best option, which coincidentally is system. This can give the illusion of a working Config.set().
Related
I use C++ Builder Tokyo 10.2.3 and trying to do something very simple on Android like typing some text into an Edit box.
If I press Next or Done key on virtual keyboard everything is fine.
If I press an Exit Button to go back the previous form it looks it is fine but then if I press Android Back button application crash.
It took me hours to identify the problem but couldn't find any solution but trying to disable all other objects when user clicks in an Edit box and enable them if user click on Next..
It seems to me a bug but need to make sure before report it to Embarcadero.
Thanks
I found the problem and a solution. In short, there is a bug in C++ Builder Tokyo 10.2.3 as if virtual keyboard on Android hide/close because of focus change on a form virtual keyboard doesn't take it as it is hidden properly.. FormVirtualKeyboardHidden working fine but I don't know somehow application crashes.
So, the solution is to using platform services. Just hide the keyboard manually on FormFocusChanged event.
void __fastcall TForm1::FormFocusChanged(TObject *Sender)
{
di_IFMXVirtualKeyboardService VirtualKeyboardService;
if(TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXVirtualKeyboardService), &VirtualKeyboardService))
{
VirtualKeyboardService->HideVirtualKeyboard();
}
}
I am trying to use Odoo with the application Barcode & QR code Keyboard, from Nikola Antonov (just an example, I do not know if there are better options), in order to read barcodes for the pickings.
The first problem I had to face was I had to show the keyboard in this picking view
So I needed to create an input field in order to click in it and show the Android Keyboard, or in this case the Nikola Antonov keyboard. Then, I had to assign the function handler to this input text field:
this.$('#input_text_barcodes').on('keyup', self.getParent().barcode_scanner.handler);
The function is only working as expected if I use the normal Android Keyboard (AOSP) and only with numbers. The letters of the Android Keyboard or whatever character of the Nikola Antonov Keyboard are not working (only the backspace)
this.handler = function(e){
self.$('#aux_label').text('>> CODE: ' + e.which)
self.$('#aux_label').text('>> KEY CODE: ' + e.keyCode)
self.$('#aux_label').text('>> KEY: ' + e.key)
// [...]
I tried switching the languages of the keyboard as well, but with the same result
Should I change the keyup event?
Is there other way to catch the characters?
Finally I have asked to the developer of the application directly and he solved the problem quite fast. He made it work with numeric keys, that is enough for what I wanted to achieve.
I'm using Cordova 3.6.4 in Visual Studio 2013 Community Update 4 to build an apps with a "chat" functionality, the main reason that I use this technology is because I want to, hopefully, write once and can use it in all platforms such as Android phones, iPhones, all mobile phone browsers, all desktop browsers.
In order to let the users inputting the "message" to be sent, I create a [div] which is contenteditable="true" at the bottom left of the html, at the right hand side of this [div], I have two [image buttons], one is the [happy face] button, the other is the [send button]. (You know, just like Whatsapp, Line and WeChat!)
At any time the user can click the [happy face] button to select one of the many "face image" to insert into the cursor at the [div], then I'll add the html codes into the [div], e.g. div.innerHTML += '< img src="1.jpg">'
So, the innerHTML of this [div] can contain characters AND images, e.g.
12< img src="1.jpg" />34< img src="2.jpg" />
Of course, the actual display is:
12[1st Picture]34[2nd Picture]
If the cursor is at the end of this [div], and I clicked the [BACKSPACE], I expect the [2nd Picture] will be removed, if I clicked the [BACKSPACE] again, I expect the letter [4] will be removed from the [div], this is work at ALMOST every platform I mentioned including all mobile browsers in android and iphone/ipad, all desktop browsers. But it does not work when I build an Android app and run it in any Android phone.
Running it as a WebView in android phone, when I click the the [BACKSPACE], the letter [4] is removed instead of the [2nd Picture], when I click the [BACKSPACE] again, the letter[3] is removed. I can NEVER remove the 2 images no matter which IME I'm using.
To work around, I tried to add a keyup/keydown/keypress listener to the [BACKSPACE] but it never fires.
At last, to work around this [BUG], I need to add a third [X] image button and use JavaScript string.replace to remove the < img> tag when users click this [X] button, but it looks very stupid to the users!
It makes me crazy that ALL IMEs do not remove the image for me by pressing the [BACKSPACE], and if the key events are not fired, I cannot remove the images myself!
I tried ALMOST, I think, ALL the suggestions provided by stackoverflow but they don't work at all, either not applicable to CORDOVA, or with compilation error such as [command failed with exit code 8] in Visual Studio.
What should I do?
in Kivy, when I press the back button on my android device it throws me out of the application. is there a way to return back to the previous screen using the Kivy language and not python? this is what I have written in kivy:
<MyAppClass>:
AnchorLayout:
anchor_x : 'center'
anchor_y : 'top'
ScreenManager:
size_hint : 1, .9
id: _screen_manager
Screen:
name:'screen1'
StackLayout:
# irrelevant code
Screen:
name:'screen2'
StackLayout:
# irrelevant code
I need to manipulate the screen manager and its screens from python... if I can do so I will be ok with python.
Kivy on android binds the back button to the esc button so binding and listening to esc button in your app would help you handle how your app behaves when the back button is pressed.
In other words in your app when testing it on your desktop listen to the escape key from the system keyboard, this will be automatically be translated to being the back button on your android device. Something like::
def on_start():
from kivy.base import EventLoop
EventLoop.window.bind(on_keyboard=self.hook_keyboard)
def hook_keyboard(self, window, key, *largs):
if key == 27:
# do what you want, return True for stopping the propagation
return True
i guess that i have solved it but should thank both #inclement and #qua-non! your answers guys led me to the right way! so in kv i assume that i gave an id to my screen manager (please refer to my question where i have written the kv code) , in python i should do the following:
from kivy.core.window import Window
from kivy.properties import ObjectProperty
class MyAppClass(FloatLayout):#its a FloatLayout in my case
_screen_manager=ObjectProperty(None)
def __init__(self,**kwargs):
super(MyAppClass,self).__init__(**kwargs)
#code goes here and add:
Window.bind(on_keyboard=self.Android_back_click)
def Android_back_click(self,window,key,*largs):
if key == 27:
self._scree_manager.current='screen1'#you can create a method here to cache in a list the number of screens and then pop the last visited screen.
return True
class MyApp(App):
def build(self):
return MyAppClass()
if __name__=='__main__':
MyApp().run()
This is certainly possible. Here's a short example app with the method I use to do this:
from kivy.utils import platform
from kivy.core.window import Window
class ExampleApp(App):
manager = ObjectProperty()
def build(self):
sm = MyScreenManager()
self.manager = sm
self.bind(on_start=self.post_build_init)
return sm
def post_build_init(self, *args):
if platform() == 'android':
import android
android.map_key(android.KEYCODE_BACK, 1001)
win = Window
win.bind(on_keyboard=self.my_key_handler)
def my_key_handler(self, window, keycode1, keycode2, text, modifiers):
if keycode1 in [27, 1001]:
self.manager.go_back()
return True
return False
This should give the right basic idea, but a few notes:
ScreenManager doesn't keep track of the previous screens, it's up to you to implement this how you like. My example assumes you defined a class MyScreenManager with a go_back method.
It might not be necessary to bind to on_start and run post_build_init, this is just how the example I originally used did it (see below). It might be important sometimes though, possibly if the window is not initialised when build() is run, and the original mailing list post suggests the author needed it for some reason.
The example listens for keycodes 27 or 1001. As qua-non said while I was writing this, the former listens for esc, so you can get the same behaviour on desktop.
I didn't try without the android.map_key line, but it seems like it may not be necessary.
You mention you want to use kivy language and not python. You need to do some python to get this result, and I don't see a way around that (it's not really the domain of the kv language). I guess you could shift some stuff to kv by defining a 'go_back' event somewhere and triggering this when the key is pressed, along with binding your screenmanager to watch that event, but it seems like a long way around.
I based my code on the mailing list thread at https://groups.google.com/forum/#!topic/kivy-users/7rOZGMMIFXI . There might be a better way, but this is quite functional.
Now all the way in 2020 I'm using:
Clock.schedule_once(lambda x: Window.bind(on_keyboard=self.hook_keyboard))
in combination with a similar hook_keyboard method to the other answers, to delay the bind in my build method. Works fine, but none of these other ways ways seemed to work for me anymore.
I'm having some issues with the softkeyboard behaviour in flex 4.6 and air 3.1
I have a list with a search bar on top. When a user selects the TextInput component the softkeyboard pops up like it should.
Now when the user is done typing his text and presses the return (or the done/search/...) key I want the softkeyboard to disappear.
What I've tried so far:
I've set the returnKeyLabel property to "done" and the button shows
up accordingly. However it only dismisses the keyboard on Android, on
IOS the keyboard just stays up.
I then tried by not setting the returnKeyLabel and manually
catching the Return key and setting the focus to another element that
does not require a softkeyboard but that didn't work either.
I also tried by dispatching my own "faked" click events when the Return key was pressed but this also didn't work.
As part of searching about this problem I found this Dismiss SoftKeyboard in Flex Mobile but that didn't work either. Or at least not in flex 4.6
Now does anyone know of a good way to hide the softkeyboard or make the returnKeyLabel "done" work on IOS that will work with flex 4.6/air 3.1?
Have you tried something like this?
<s:TextInput prompt="First Name" returnKeyLabel="done" enter="handlerFunction()"/>
private function handlerFunction():void{
stage.focus = null
}
For flex mobile android apps I have mimicked the intuitive ios way of tapping on the background to remove the softkeyboard as follows:
import spark.components.supportClasses.*
protected function application1_clickHandler(event:MouseEvent):void
{
if(event.target is StyleableTextField || event.target is StyleableStageText){
// ignore because came from a textInput
}else{
stage.focus = null
// to remove the softkeyboard
}
}
<s:TextInput prompt="First Name" returnKeyLabel="done" enter="{stage.focus = null}"/>
This is the same as Francis' answer, but it saves having to make a new function