I'm trying to find a way to use libavg's event handlers from an embedded serial output. My understanding is that I need to create my own Publisher that I will call when I process serial commands. All I need is a way to create 10 different triggers given different serial inputs. An analogy of what I am trying to do would be to use libavg's keyboard handling to process different keyboard inputs.
I want the custom publisher to take the 10 serial outputs and pass a event.serialid parameter to various subscribers similarly to what event.keystring does.
Here is some nonfunctional code that I have that I think has the basics of what needs to be done.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from libavg import avg, statemachine, player
class Test():
PRESSED = avg.Publisher.genMessageID()
RELEASED = avg.Publisher.genMessageID()
def __init__(self, parent=None, **kwargs):
self.registerInstance(self, parent)
self.publish(self.PRESSED)
self.publish(self.RELEASED)
def isActive(self):
self.notifySubscribers(Test.PRESSED, [])
def isInactive(self):
self.notifySubscribers(Test.RELEASED, [])
def onKeyDown(event):
global node
if event.serialid == '1':
#serialid isn't implemented anywhere but this is what ideally I would like to have happen
node.color = "FF8000"
def onKeyUp(event):
global node
node.color = "FFFFFF"
player = avg.Player.get()
canvas = player.createMainCanvas(size=(640,480))
rootNode = player.getRootNode()
node = avg.WordsNode(pos=(10,10), font="arial", text="Hello World", parent=rootNode)
vbutton=Test()
node.subscribe(vbutton.PRESSED, onKeyDown)
node.subscribe(vbutton.RELEASED, onKeyUp)
player.play()
examples of custom publishers from here:
class _ButtonBase(avg.DivNode):
PRESSED = avg.Publisher.genMessageID()
RELEASED = avg.Publisher.genMessageID()
def __init__(self, parent=None, **kwargs):
super(_ButtonBase, self).__init__(**kwargs)
self.registerInstance(self, parent)
self.publish(self.PRESSED)
self.publish(self.RELEASED)
def _setActiveArea(self, upNode, activeAreaNode, fatFingerEnlarge):
self.__activeAreaNode = activeAreaNode
if fatFingerEnlarge:
if self.__activeAreaNode != None:
raise(RuntimeError(
"Button: Can't specify both fatFingerEnlarge and activeAreaNode"))
size = upNode.size
minSize = 20*player.getPixelsPerMM()
size = avg.Point2D(max(minSize, size.x), max(minSize, size.y))
self.__activeAreaNode = avg.RectNode(size=size, opacity=0, parent=self)
else:
if self.__activeAreaNode == None:
self.__activeAreaNode = self
else:
self.appendChild(self.__activeAreaNode)
self._tapRecognizer = gesture.TapRecognizer(self.__activeAreaNode,
possibleHandler=self._onDown,
detectedHandler=self._onTap,
failHandler=self._onTapFail)
You can pass arbitrary parameters through the publish-subscribe interface. The parameter(s) are passed as a list:
self.notifySubscribers(Test.PRESSED, [serialID])
And in the handler:
def onKeyDown(serialID):
global node
if serialid == '1':
node.color = "FF8000"
Related
LibreOffice 5.3, python 3.53, VOID Linux
This is more of an uno question than a python question. The code below does a simple update of 3 cells. 3 buttons configured on the sheet calling dowriteonce() dowritetwice() and dowritethrice(), and they all update and work like you might expect writing numbers and text to selected cells.
Where the problem comes in, is that when a cell is edited in the UI by a user, any subsequent update of that cell by means of executing the function is blocked. So simply clicking cell C4 in the calc UI, prevents the writethrice() function from updating cell C4. If I delete the content and click another cell in the UI, say C5, then everything works normally again and C4 updates when the button is clicked.
What I would like to do is relocate the UI edit-cursor to an unused cell prior to execution in order to prevent this. User copy-paste is going to leave the active cursor in unpredictable places and that will bork calculations if I can't isolate the cursor.
So the question is, how do I move the UI edit cursor to a named cell via the UNO API, with Python? Or if it is easier, just deactivate it temporarily.
Python:
import socket
import sys
import re
import uno
import unohelper
class ODSCursor(unohelper.Base):
# predeclare class properties
ctx=None
desktop=None
model=None
activesheet=None
counter=0
scooby="Scooby"
# import namespaces
def __init__(self):
import socket
import uno
import unohelper
import sys
import re
# initialize uno handle only once and get the first sheet
#classmethod
def sheet1(cls,*args):
if cls.activesheet is not None:
return (cls.activesheet)
cls.ctx = uno.getComponentContext()
cls.desktop = cls.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", cls.ctx)
cls.model = cls.desktop.getCurrentComponent()
# cls.activesheet = cls.model.Sheets.getByName("Sheet1")
cls.activesheet = cls.model.Sheets.getByIndex(0)
return (cls.activesheet)
#classmethod
def writeonce(self,*args):
self.counter += 1
cell_b1 = self.activesheet.getCellRangeByName("B1")
cell_b1.String = self.counter
#classmethod
def writetwice(self,*args):
self.counter += 1
cell_b2 = self.activesheet.getCellRangeByName("B2")
cell_b2.String = self.counter
#classmethod
def writescooby(self,*args):
cell_c4 = self.activesheet.getCellRangeByName("C4")
cell_c4.String = self.scooby
### BUTTON BOUND FUNCTIONS ###
def dowriteonce(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writeonce()
def dowritetwice(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writetwice()
def dowritethrice(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writescooby()
In the following code, cells are deselected before changing the values, then selected again. This way, cells can be modified even when left in edit mode by the user.
There also seems to be some confusion about Python class methods and variables, so I changed those parts as well.
import uno
import unohelper
SCOOBY = "Scooby"
class ODSCursor(unohelper.Base):
def __init__(self):
self.ctx = None
self.desktop = None
self.document = None
self.controller = None
self.sheet = None
self.counter = 0
def sheet1(self):
"""Initialize uno handle only once and get the first sheet."""
if self.sheet is not None:
return self.sheet
self.ctx = uno.getComponentContext()
self.desktop = self.ctx.ServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", self.ctx)
self.document = self.desktop.getCurrentComponent()
self.controller = self.document.getCurrentController()
self.sheet = self.controller.getActiveSheet()
return self.sheet
def writeonce(self):
self.writeval("B1", self.inc())
def writetwice(self):
self.writeval("B2", self.inc())
def writescooby(self):
self.writeval("C4", SCOOBY)
def writeval(self, address, value):
self.deselect()
cell = self.sheet.getCellRangeByName(address)
cell.String = value
self.controller.select(cell)
def deselect(self):
"""Select cell A1, then select nothing."""
cell_a1 = self.sheet.getCellByPosition(0, 0)
self.controller.select(cell_a1)
emptyRanges = self.document.createInstance(
"com.sun.star.sheet.SheetCellRanges")
self.controller.select(emptyRanges)
def inc(self):
"""Increment the counter and return the value."""
self.counter += 1
return self.counter
odsc = ODSCursor()
### BUTTON BOUND FUNCTIONS ###
def dowriteonce(dummy_oEvent):
odsc.sheet1()
odsc.writeonce()
def dowritetwice(dummy_oEvent):
odsc.sheet1()
odsc.writetwice()
def dowritethrice(dummy_oEvent):
odsc.sheet1()
odsc.writescooby()
I have 2 classes:
1 which contains the data and another that contain an array
how can I create a function that add that class (like a list)
class Event(object):
def __init__(self):
self.msg_idx=0 ## the message from the panel
self.evt_id=0 ## the event id given by the server
self.Panel_Number=0 ## the panel number
self.line=""
def updateData(self,msg,event,panel,line):
self.msg_idx =msg
self.evt_id = event
self.Panel_Number = panel
self.line =line
class Events(object):
def __init__(self):
self.event =[]
def addEvent(self, Server_Event):
????????
Literally just append:
class Event(object):
def __init__(self):
self.msg_idx=0 ## the message from the panel
self.evt_id=0 ## the event id given by the server
self.Panel_Number=0 ## the panel number
self.line=""
def updateData(self,msg,event,panel,line):
self.msg_idx =msg
self.evt_id = event
self.Panel_Number = panel
self.line =line
class Events(object):
def __init__(self):
self.event =[]
def addEvent(self, Server_Event):
self.event.append(Server_Event)
something = Event()
somethings = Events()
somethings.addEvent(something)
I would question why you need such a class right now, when you could just use a list called events. But I have done something similar before and I know it makes it easier to add metadata on top.
However if you're just using it for the above without any extra analysis, it would be more efficient to just use a list.
I've wrote an little app to scroll an stock market ticker into a Tkinter window and update the stock values every minute using a threading class.
If I closed the window the main process didn't stops, then I've implemented a method to close the window and stop the thread. But when I close the window the main process delay the stopping to the next call to the theading.run() method.
How can I get that an instant closing process?
The code:
# -*- coding: UTF-8 -*-
import tkinter as tk
import tkinter.messagebox
import time
import threading
from random import randint as randint, uniform as randlimit
# Here starts the program working process, until here was the GUI
# CONSTANTS
CHAR_UP = "\u25B2"
CHAR_DOWN = "\u25BC"
CHAR_EVEN = "="
UPDATE_TIME = 60
# INITIAL DATA, this must be changed to implement the load of a external source
stock_market = [["GOOG", "587.25", CHAR_UP, "(+12.14)"],
["AAPL", "237.14", CHAR_UP, "(+7.25)"],
["GTAT", "87.47", CHAR_DOWN, "(-1.18)"],
["KNDI", "167.32", CHAR_UP, "(+6.85)"],
["ORCL", "482.91", CHAR_DOWN, "(-24.65)"],
["FBOK", "327.67", CHAR_DOWN, "(-11.78)"],
["TWTR", "842.41", CHAR_UP, "(+15.45)"]]
class AplicationTkinter(tk.Frame):
"""
Class of tkinter.Frame subclass, Initializes the GUI
constants:
SPEED, the delay in millisecs of the scroll
attributes:
parent, the root Tk object
"""
SPEED = 250
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self._initGUI()
self._scroll_ticker()
self.parent.protocol("WM_DELETE_WINDOW",self.stop)
# or toplevel.protocol(...
def _initGUI(self):
"""
initGUI, draws the layout.
"""
# changes the window icon
self.parent.iconbitmap("tabla.ico")
self.parent.title("Stock Exchange Ticker")
# fix a status bar at the bottom of the window, for future improvements
self.status_bar = tk.Label(self.parent, text="", bd=1, relief=tk.SUNKEN,
anchor=tk.W)
self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
# content Frame for entry, for future improvements
self.frame = tk.Frame(self.parent)
self.frame.pack()
self.var_entry = tk.StringVar()
self.entry = tk.Entry(self.frame, textvariable=self.var_entry)
self.entry.pack()
self.var_entry.set("a default value")
str_ent_1 = self.entry.get()
# content LabelFrame to show the ticker scrolling line of text
self.label_frame = tk.LabelFrame(self.parent,
text="Ventana de Resultados")
self.label_frame.pack()
# creates an instance of the StockMarket class for contents the data
self.market_one = StockMarket(stock_market)
# the scrolling line of Text for show the data
self.txt_ticker_widget = tk.Text(self.label_frame, background='black',
height=1, width=56, wrap="none")
self.txt_ticker_widget.pack(side=tk.TOP, fill=tk.X)
self.txt_ticker_widget.tag_configure("up", foreground="green")
self.txt_ticker_widget.tag_configure("down", foreground="red")
self.txt_ticker_widget.tag_configure("even", foreground="white")
self.tag = {CHAR_DOWN: "down", CHAR_EVEN: "even", CHAR_UP: "up"}
def _scroll_ticker(self):
"""
scroll_ticker, inserts character by character in the Text widget
"""
self.txt_ticker_widget.configure(state=tk.NORMAL)
self.txt_ticker_widget.insert(tk.END,
self.market_one.get_next_character(),
self.tag[self.market_one.get_tag()])
# TODO simplify
self.txt_ticker_widget.see(tk.END)
self.txt_ticker_widget.configure(state=tk.DISABLED)
self.txt_ticker_widget.after(self.SPEED, self._scroll_ticker)
# recursive each interval of millisecs, constant SPEED
def stop(self):
if tk.messagebox.askokcancel("Quit?", "Are you sure you want to quit?"):
# self.destroy()
print("STOPPING !!")
self.market_one.thread_updating.stop()
self.destroy()
self.parent.quit()
class StockTicker():
"""
Class StockTicker, handle each stock symbol and their data
attributes:
symbol, string, the abbreviature of the securitie
price, string, the current price of the securitie
direction, string(1), is a character that indicates its las fix price
went up, down or even
change, string, is the value of the last change surrounded by '()',
the first character is '+' or '-'
"""
def __init__(self, list_data):
self.symbol, self.price, self.direction, self.change = list_data
def update_ticker(self):
"""
update_ticker, update the securitie price, direction and
change with random values
"""
flt_price = float(self.price)
if randint(0, 9) == 0:
self.direction = CHAR_EVEN
else:
increase_percent = randlimit(-5, 5)
# TODO implementar normalvariate(0, 0.02) o gauss(0, 0.02)
flt_change = flt_price * increase_percent / 100
flt_new_price = flt_price + flt_change
self.price = "{:.2f}".format(flt_new_price)
if flt_change < 0:
self.direction = CHAR_DOWN
elif flt_change == 0:
self.direction = CHAR_EVEN
else:
self.direction = CHAR_UP
self.change = "({:+.2f})".format(flt_change)
def ticker_to_text(self):
"""
ticker_to_text, returns a formatted string with all the data of
the securitie.
"""
return " | {} {} {} {} ".format(self.symbol, self.price,
self.direction, self.change)
class StockMarket():
"""
Class StockMarket, creates and handle a list of StockTicker objects,
and provide to the GUI of stuff for the scroll ticker
attributes:
smarket, list of StockTicker objects
thread_actualizar, Thread object to update the stock market
each time interval
"""
def __init__(self, l_inicial):
self.tickers = []
self.index = 0
self._load(l_inicial)
self.current_ticker = self._get_one_ticker()
self.thread_updating = UpdateThread(self)
self.thread_updating.start()
def _load(self, l_inicial):
"""
load_market, load the list with StockTicker object taking the data from
the initial source data.
"""
for data_ticker in l_inicial:
simple_ticker = StockTicker(data_ticker)
self.tickers.append(simple_ticker)
def update_market(self):
"""
update_market, update the objects of the list
"""
for ticker in self.tickers:
ticker.update_ticker()
def _get_one_ticker(self):
"""
get_one_ticker, getter function to return one securitie data in text
format and rotates to the next one
"""
self.one_ticker = self.tickers.pop(0)
self.tickers.append(self.one_ticker)
self.index = 0
return self.one_ticker.ticker_to_text()
def get_next_character(self):
"""
get_next_character, returns a character of one securitie
(if the securitie data is exhausted retrieve another securitie)
data to the GUI.
"""
if self.index == len(self.current_ticker):
self.current_ticker = self._get_one_ticker()
self.index = 0
character_symbol = self.current_ticker[self.index:self.index+1]
self.index += 1
return character_symbol
def get_tag(self):
return self.one_ticker.direction
class UpdateThread(threading.Thread):
"""
Class UpdateThread(), subclass of Thread, handle the time to the next
update of the stock market values
args:
market_1, a StockMarket class object to update
attributes:
my_check, string for debugging purpouses, it'll be implemented the
source data management the_market, StockMarket object that will
be updated
"""
def __init__(self, market_1):
self.my_check = " CHECK " # TODO replace with initial source data.
self.the_market = market_1
self.is_quit = False
threading.Thread.__init__(self)
def run(self):
"""
run, overrides the Thread run method, and calls the update_market
method of StockMarket class each interval
"""
time.sleep(UPDATE_TIME)
self.the_market.update_market()
print(" UPDATED!!!") # for debugging
if not self.is_quit:
self.run()
def stop(self):
"""
stop, for stopping the thread when event occurs
"""
self.is_quit = True
# STARTS THE PROGRAM
def main():
the_window = tk.Tk()
aplication = AplicationTkinter(the_window)
# init the GUI process
the_window.mainloop()
if __name__ == '__main__':
main()
Is there trivial or elegant way to differentiate between many same-type signal sources in PySide/PyQt?
I am learning PySide. I have written simple application, which multiplies two numbers from two different QLineEdit() objects. Result is displayed in third QLineEdit.
Multiplier and multiplicand QLineEdit.textChanged() signals are connected to one method (TxtChanged). In this method i have to differentiate between signal sources. After some trials I figured out some workaround based upon placeholder text (4 lines below "is there another way?" comment in my code)
code:
import sys
from PySide import QtGui, QtCore
class myGUI(QtGui.QWidget):
def __init__(self, *args, **kwargs):
QtGui.QWidget.__init__(self, *args, **kwargs)
self.multiplier = 0
self.multiplicand = 0
self.myGUIInit()
def myGUIInit(self):
# input forms
a1_label = QtGui.QLabel("a1")
a1_edit = QtGui.QLineEdit()
a1_edit.setPlaceholderText("a1")
a2_label = QtGui.QLabel("a2")
a2_edit = QtGui.QLineEdit()
a2_edit.setPlaceholderText("a2")
# output form
a1a2_label = QtGui.QLabel("a1*a2")
self.a1a2_edit = QtGui.QLineEdit()
self.a1a2_edit.setReadOnly(True)
# forms events
a1_edit.textChanged.connect(self.TxtChanged)
a2_edit.textChanged.connect(self.TxtChanged)
# grid
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(a1_label,1,0)
grid.addWidget(a1_edit,1,1)
grid.addWidget(a2_label,2,0)
grid.addWidget(a2_edit,2,1)
grid.addWidget(a1a2_label,3,0)
grid.addWidget(self.a1a2_edit,3,1)
self.setLayout(grid)
self.setGeometry(100,100,200,200)
self.setWindowTitle("a*b")
self.show()
def TxtChanged(self,text):
sender = self.sender()
sender_text = sender.text()
if sender_text == '': sender_text = '0'
# is there another way?
if sender.placeholderText() == 'a1':
self.multiplicand = sender_text
else:
self.multiplier = sender_text
product = int(self.multiplier) * int(self.multiplicand)
print(self.multiplier,self.multiplicand,product)
self.a1a2_edit.setText(str(product))
def main():
app = QtGui.QApplication(sys.argv)
mainWindow = myGUI()
sys.exit(app.exec_())
main()
best regards,
ostrzysz
You can use the functools.partial function - and therefore connect your signals to straight to your method/function but rather to a python object which will automatically call your function with some extra data you pass it:
from functools import partial
...
....
a1_edit.textChanged.connect(partial(self.TxtChanged, a1_edit))
a2_edit.textChanged.connect(partial(self.TxtChanged, a2_edit))
...
def TxtChanged(self,sender, text):
# and here you have the "sender" parameter as it was filled in the call to "partial"
...
partials is part of the stdlib, and is very readable, but one can always use lambda instead of partial for the same effect -
a1_edit.textChanged.connect(lambda text: self.TxtChanged(a1_edit, text))
In this way the object yielded by the lambda expression will be a temporary function that will use the values for "self" and "a1_edit" from the current local variables (at the time the button is clicked), and the variable named "text" will be supplied by Pyside's callback.
One thing that bugs me most in your code is that you are using placeholderText to differentiate. QObjects has another property called objectName that is more suitable for your task. And, you don't need to use sender.text() to get the text of QLineEdit. textChanged already sends it, so you will have it in your text parameter.
Also, using a dictionary instead of two separate variables (multiplier and multiplicand) will simplify your code further.
Here is the changed code:
class myGUI(QtGui.QWidget):
def __init__(self, *args, **kwargs):
QtGui.QWidget.__init__(self, *args, **kwargs)
self.data = {"multiplier": 0,
"multiplicand": 0}
self.myGUIInit()
def myGUIInit(self):
a1_label = QtGui.QLabel("a1")
a1_edit = QtGui.QLineEdit()
a1_edit.setObjectName("multiplicand")
a2_label = QtGui.QLabel("a2")
a2_edit = QtGui.QLineEdit()
a2_edit.setObjectName("multiplier")
# skipped the rest because same
def TxtChanged(self, text):
sender = self.sender()
# casting to int while assigning seems logical.
self.data[sender.objectName()] = int(text)
product = self.data["multiplier"] * self.data["multiplicand"]
print(self.data["multiplier"], self.data["multiplicand"], product)
self.a1a2_edit.setText(str(product))
Although #jsbueno and #Avaris answered your direct question about signal sources, I wouldn't relay on this sources in your concrete case. You can make instance members a1_edit and a2_edit:
...
self.a1_edit = QtGui.QLineEdit()
...
self.a2_edit = QtGui.QLineEdit()
...
It will simplify your TxtChanged function:
def TxtChanged(self,text):
try:
multiplier = int(self.a1_edit.text())
multiplicand = int(self.a2_edit.text())
except ValueError:
self.a1a2_edit.setText('Enter two numbers')
return
product = multiplier * multiplicand
print(multiplier, multiplicand, product)
self.a1a2_edit.setText(str(product))
Also, instead of handling ValueError exception, you can use QIntValidator for input controls:
self.int_validator = QtGui.QIntValidator()
self.a1_edit.setValidator(self.int_validator)
self.a2_edit.setValidator(self.int_validator)
I'm trying to remap several navigation keys:
ENTER: to work like standard TAB behavior (focus to next control)
SHIFT+ENTER: to work like SHIFT+TAB behavior (focus to previous control)
UP / DOWN arrows: previous /next control
etc
I tried with a couple of options but without luck:
from javax.swing import *
from java.awt import *
class JTextFieldX(JTextField):
def __init__(self, *args):
# Thanks, Jack!!
JTextField.__init__(
self,
focusGained=self.onGotFocus,
focusLost=self.onLostFocus,
*args)
def onGotFocus (self, event):
print "onGotFocus "
self.selectionStart = 0
self.selectionEnd = len(self.text)
def onLostFocus (self, event):
print "onLostFocus ", self.name
class Test(JFrame):
def __init__(self):
JFrame.__init__(self,
'JDesktopPane and JInternalFrame Demo',
size=(600, 300),
defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
self.desktop = JDesktopPane()
self.contentPane.add(JScrollPane(self.desktop)) # This is the same as self.getContentPane().add(...)
frame = JInternalFrame("Frame", 1, 1, 1, 1, size=(400, 400), visible=1)
panel = JPanel()
self.label = JLabel('Hello from Jython')
panel.add(self.label)
self.textfield1 = JTextFieldX('Type something here', 15)
panel.add(self.textfield1)
self.textfield2 = JTextFieldX('and click Copy', 15)
panel.add(self.textfield2)
panel.add(copyButton)
frame.add(panel)
frame.pack()
self.desktop.add(frame)
# ENTER=SPACE remapping for buttons (works ok, but only for buttons)
# inputMap = UIManager.getDefaults().get("Button.focusInputMap")
# pressedAction = inputMap.get(KeyStroke.getKeyStroke("pressed SPACE"));
# releasedAction = inputMap.get(KeyStroke.getKeyStroke("released SPACE"));
# # pressedAction = self.noAction
# inputMap.put (KeyStroke.getKeyStroke("pressed ENTER"), pressedAction)
# inputMap.put (KeyStroke.getKeyStroke("released ENTER"), releasedAction)
# # Attemp to remap ENTER=TAB for TextFields (didn't work, no errors)
# inputMap = UIManager.getDefaults().get("TextField.focusInputMap")
# pressedAction = inputMap.get(KeyStroke.getKeyStroke("pressed TAB"));
# releasedAction = inputMap.get(KeyStroke.getKeyStroke("released TAB"));
# inputMap.put (KeyStroke.getKeyStroke("pressed W"), pressedAction)
# inputMap.put (KeyStroke.getKeyStroke("released W"), releasedAction)
# # Attemp to remap ENTER=TAB for all controls (didn't work, no errors)
# spaceMap = self.textfield1.getInputMap().get(KeyStroke.getKeyStroke(event.KeyEvent.VK_TAB, 0, True));
# self.textfield1.getInputMap().put(KeyStroke.getKeyStroke(event.KeyEvent.VK_ENTER, 0, True),spaceMap);
frame.setSelected(1)
frame.moveToFront()
def noAction (self, event):
print "noAction"
pass
if __name__ == '__main__':
test = Test()
test.setLocation(100, 100)
test.show()
I made a new post for readability.
self.textfield1 = JTextField('Type something here',15,focusGained=self.myOnFocus,keyPressed=self.myOnKey)
#create textfield2...must be created before can be referenced below.
self.textfield1.setNextFocusableComponent(self.textfield2)
then in your event handler:
def myOnKey(self,event):
print str(event) # see all other info you can get.
key_code = event.keyCode
if key_code == 10:
print "you pressed enter"
# simulate the "tab" just focus next textbox...
gotFocus = event.getComponent()
nextToFocus = gotFocus.nextFocusableComponent
nextToFocus.requestFocus()
Should do it.
Finally used part of Jack's answer (the keyPressed event) but without manually setting setNextFocusableComponent:
keyFocusMgr = KeyboardFocusManager.getCurrentKeyboardFocusManager()
keyFocusMgr.focusNextComponent()
Add keyPressed to the swing competent that you want to listen for the key press on
self.textfield1 = JTextField('Type something here',15,focusGained=self.myOnFocus,keyPressed=self.myOnKey)
myOnKey can be named anything in that method do something like:
def myOnKey(self,event):
print str(event) # see all other info you can get.
key_code = event.keyCode
if key_code == 10:
print "you pressed enter"
# simulate the "tab" by just focusing the next textbox...
Then you should just be able to play around with the print str(event) command to get all the proper keycodes that you want.