Pretty much what the title says. How can i change NAO's Chest and Feet LEDs. I know they support RGB but how do i command what colours they stay at?
I found a way to do it. It was actually quite simple.
I altered the code of the "Eye LEDs" box.
If you double click it it will show you 2 other boxes, "Color Edit" and "Eyes LEDs".
I simply altered the code of the second "Eyes LEDs" box with this one:
class MyClass(GeneratedClass):
def __init__(self):
GeneratedClass.__init__(self, False)
def onLoad(self):
self.fadeOps = []
self.leds = self.session().service("ALLeds")
def onUnload(self):
#~ puts code for box cleanup here
pass
def onInput_color(self, p):
if( self.getParameter("Side") == "Left" ):
sGroup = "AllLeds"
elif( self.getParameter("Side") == "Right" ):
sGroup = "AllLeds"
else:
sGroup = "AllLeds"
fadeOp = self.leds.fadeRGB(sGroup, 256*256*p[0] + 256*p[1] + p[2], self.getParameter("Duration (s)"), _async=True)
self.fadeOps.append(fadeOp)
fadeOp.wait()
self.fadeOps.remove(fadeOp)
if( self.fadeOps == [] ):
self.onDone() # activate output of the box
Technically all I did is change all the "sGroup = ... " to sGroup = "AllLeds"
Related
I currently try to create a game with pygame, after defining the sprite Enemy, Player, and Skill, I hope the function of the skill is that the Player shoots the skill to the nearest Enemy per second, how do I get the nearest Enemy position?
While I used for loop to display the Enemy sprite in range(8) randomly from the edge of the game screen, and after one Enemy gets killed, the new enemy will be displayed. But when I use for loop, how could I know which one is sprite[1] and which one is sprite[2] followingly? Is there any way to put the sprites I created in a list or something else? So as that I can analyze which one is the nearest and let the Skill track it and kill it.
The Enemy sprite class:
`
class Enemy(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.transform.scale(ayu_img, (64, 64)) # sprite elements
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect() # sprite location fixed
self.radius = 32
randomNum = random.randrange(1, 4) # Dice for 1 to 4 condition
if randomNum == 1:
self.rect.x = random.randrange(-40, -32)
self.rect.y = random.randrange(0, HEIGHT - self.rect.height)
elif randomNum == 2:
self.rect.x = random.randrange(WIDTH + 32, WIDTH + 40)
self.rect.y = random.randrange(0, HEIGHT - self.rect.height)
elif randomNum == 2:
self.rect.x = random.randrange(0, WIDTH - self.rect.width)
self.rect.y = random.randrange(-40, -32)
elif randomNum == 4:
self.rect.x = random.randrange(0, WIDTH - self.rect.width)
self.rect.y = random.randrange(HEIGHT + 32, HEIGHT +40)
self.speedx = random.randrange(1, 2)
self.speedy = random.randrange(1, 2)
def update(self):
if self.rect.centerx > player.rect.centerx: # movement judge
self.rect.centerx -= self.speedx
else:
self.rect.centerx += self.speedx
if self.rect.centery > player.rect.centery:
self.rect.centery -= self.speedy
else:
self.rect.centery += self.speedy
`
The way I create enemy in game
`
for i in range(8):
enemy = Enemy() # create entity
all_sprites.add(enemy) # put into the sprite list
enemies.add(enemy) # put into the enemy list
`
is there any way to make enemy to enemy[ i ] for i in range(8)? or someway else? I am not sure if my idea is good or there is a simplified way to do it ...
A pygame.sprite.Groups can be iterated:
for sprite in all_sprites:
# [...]
of course you can enumerate the sprites:
for i, sprite in enumerate(all_sprites):
# [...]
and you can get a list of Sprites with pygame.sprite.Group.sprites:
sprite_list = all_sprites.sprites()
if len(sprite_list) > 0:
sprite_0 = sprite_list[0]
# [...]
I would like to show/hide a grid on a tkinter canvas, as seen in Gimp for instance.
I have this code:
is_on = True
def my_grid():
global is_on
global hor
global ver
if is_on:
y=0
x=0
for i in range(8):
x+=64
y+=64
hor=A.create_line(0,y,512,y, fill="black")
ver=A.create_line(x,0, x, 512, fill="black")
is_on=False
else:
A.delete(hor)
A.delete(ver)
is_on=True
This delete only the last row and the last column. I've also tried to loop the delete action but it doesn't work.
Hope someone could help me.
Best
If you add a tag to the lines, you can manipulate all of the lines with a single statement.
Also, there's no need to delete and recreate the lines each time. You can hide the grid by setting their state to "hidden".
For example, here's how to create, hide, and show the grid:
def create_grid():
x = y = 0
for i in range(8):
x+=64
y+=64
A.create_line(0,y,512,y, fill="black", tags=("grid",))
A.create_line(x,0, x, 512, fill="black", tags=("grid",))
def show_grid():
A.itemconfigure("grid", state="normal")
def hide_grid():
A.itemconfigure("grid", state="hidden")
Try something like this:
import tkinter as tk
class CanvasGrid(tk.Canvas):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.lines = []
self.lines_displayed = False
def display_lines(self):
# If the lines are already displayed don't do anything
if self.lines_displayed:
return None
self.lines_displayed = True
# Clear the list of the lines as they are no longer on the screen
self.lines.clear()
# Get the width and height of the canvas
width = super().winfo_reqwidth()
height = super().winfo_reqheight()
# Loop through and create the vertical lines
for x in range(0, width-width//8, width//8):
line = super().create_line(x, 0, x, height, fill="black")
self.lines.append(line)
# Loop through and create the horizontal lines
for y in range(0, height-height//8, height//8):
line = super().create_line(0, y, width, y, fill="black")
self.lines.append(line)
def hide_lines(self):
# For each line that is on the screen
for line in self.lines:
# Delete the line
super().delete(line)
self.lines_displayed = False
# Example code that uses the class
def toggle_lines(event):
if canvas.lines_displayed:
canvas.hide_lines()
else:
canvas.display_lines()
root = tk.Tk()
canvas = CanvasGrid(root, width=400, height=400)
canvas.pack()
canvas.display_lines()
canvas.bind("<Button-1>", toggle_lines)
root.mainloop()
I created an extension to the tkinter.Canvas class by adding display_lines and hide_lines. You can use the class as if you are using tkinter.Canvas but it has those 2 methods. To try out the example code click on the canvas to show/hide the lines.
Here is another way of doing this:
from tkinter import Tk, Canvas, Button
vertical = 8
horizontal = 8
canvas_width = 700
canvas_height = 500
grid_lst = []
def grid(mode):
if mode == 'show':
if len(grid_lst):
return
for hor in range(horizontal):
y = (hor + 1) * (canvas_height / (horizontal + 1))
grid_lst.append(canvas.create_line((0, y, canvas_width, y), fill='black'))
for ver in range(vertical):
x = (ver + 1) * (canvas_width / (vertical + 1))
grid_lst.append(canvas.create_line((x, 0, x, canvas_height), fill='black'))
if mode == 'hide':
for line in grid_lst:
canvas.delete(line)
grid_lst.clear()
root = Tk()
canvas = Canvas(root, width=canvas_width, height=canvas_height, bg='grey')
canvas.pack()
Button(root, text='Show Grid', command=lambda: grid('show')).pack(side='left', fill='x', expand=True)
Button(root, text='Hide Grid', command=lambda: grid('hide')).pack(side='right', fill='x', expand=True)
root.mainloop()
This method uses just one function that has an argument which determines what to do with grid: either show or hide. It also uses variables in a way that changing them would also auto-adjust the grid: vertical, horizontal, canvas_width, canvas_height. And they do what they say. vertical determines the amount of vertical lines and horizontal determines the amount of horizontal lines so this is pretty adjustable and "dynamic".
EDIT: improved performance so that lines don't add up to the list if the grid('show') is called multiple times and so that the list gets cleared when grid('hide') is called.
i'm working on this code.i want to make it display the text from the checkbutton on the label, and also remove the text when the checkbutton is not being checked.the first question is i can't remove it since the system responses
TypeError: list indices must be integers or slices, not str
the other question is i want to make a shuffle button which can shuffle the text in the label.i tried random.shuffle() but it seems doesn't work. thanks in advance!!
import tkinter as tk
import random
window = tk.Tk()
checkbutton_frame = tk.Frame(window)
checkbutton_frame.grid(column=0, row=1)
contentvar = tk.StringVar()
label = tk.Label(window, textvariable=contentvar,
bg='white', font=('Arial', 10), width=20, height=20, wraplength=50)
label.grid(column=6, row=1, padx=20,
pady=20, columnspan=2)
cb_list = ['ray', 'kevin', 'jacky']
cb_vars = []
checked = []
check_list = 1
def display():
for text, var in zip(cb_list, cb_vars):
if var.get():
checked.append(text)
contentvar.set(list(set(checked)))
else:
for i in checked:
del checked[i]
def shuffle():
random.shuffle(checked)
for r, element in enumerate(cb_list):
var = tk.BooleanVar(window, False)
cb = tk.Checkbutton(checkbutton_frame, variable=var,
text=element, command=display)
cb.grid(column=check_list, row=r, sticky='w')
cb_vars.append(var)
shuffle_button = tk.Button(window, text='SHUFFLE', command=shuffle)
shuffle_button.grid(column=8, row=2)
window.mainloop()
In the function display() you have:
else:
for i in checked:
del checked[i]
but checked is a string, so i will be a string. Try:
for i, dummy in enumerate(checked):
There were a few more things: the function display() appends to the list checked for checked items even if they are already there. This makes it look like the delete does not work. You can't see that you have to many of any item as you put them through a set before you load them into the label as set doesn't allow identical items.
Then you should set the contentvar after all processing, i.e. last in the function. Here's a version that works:
def display():
for text, var in zip(cb_list, cb_vars):
if var.get():
if text not in checked:
checked.append(text)
else:
if text in checked:
checked.remove(text)
contentvar.set(checked)
Now the texts in the label appear in the order you put them there.
The function shuffle() works just fine and shuffles the list checked. But you will have to load it into the label as well:
def shuffle():
random.shuffle(checked)
contentvar.set(checked)
I can't figure out what else I need for the combobox to select
from my list as I type. Eventually I'm going to add SetInsertionPoint.
But for now, my item selected is allways -1
self.filter = wx.ComboBox(self, wx.ID_ANY, choices = '', style=wx.CB_DROPDOWN)
def OnTextChanged(self, event):
sel = self.filter.GetSelection()
print 'OnItemSelected %s' % sel
This other SO answer has a custom control that might work for you:
Auto-Completion In wxPython wxComboBox
You may also get ideas from this wxPython wiki article
http://wiki.wxpython.org/TextCtrlAutoComplete
I also noticed that the masked combo box may have this feature itself, according to the docs: http://www.wxpython.org/docs/api/wx.lib.masked.combobox-module.html which says the following
BaseMaskedComboBox - Base class for generic masked edit comboboxes; allows auto-complete of values.
To use the GetSelection() alone, you need to set the ComboBox to read only. It's a nice way to
query by hitting one charactor. Using SetInsertionPoint and SetMark keeps the curser to the next string of your query. I used the example Mike suggested •Auto-Completion In wxPython wxComboBox
and modified my code to used these instances. Since I always use boxsizers and open functions I needed to do away with the wx.EVT_TEXT event. Here's how it works:
## copy/paste to text file
'''
73,"N WASHINGTON ST"
95,"BRIAR CREEK RD"
97,"N INDEPENDENCE AVE"
09,"N ADAMS ST"
13,"N JEFFERSON ST"
19,"N MADISON ST"
21,"QUAIL CREEK DR"
24,"INDIAN DR"
12,"CHEROKEE TRAIL"
50,"CORONADO TRAIL"
'''
import wx, os
from cStringIO import StringIO
import csv
class MainFrame(wx.Frame):
def __init__(self, parent, choices=[], style=0):
wx.Frame.__init__(self,None,wx.ID_ANY,title='test combo autocomplete',size=(225, 70))
self.vbox= wx.BoxSizer(wx.VERTICAL)
self.background = wx.Panel(self)
self.OpenDir = wx.TextCtrl(self,style=wx.PROCESS_ENTER|wx.TE_CENTRE)
self.filter = wx.ComboBox(self, wx.ID_ANY, style=wx.CB_DROPDOWN)
self.OpenDir.Bind(wx.EVT_LEFT_UP,self.OnChooseRoot)
self.filter.Bind(wx.EVT_TEXT, self.OnTextChanged)
hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
hsizer1.Add(self.OpenDir,1)
hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
hsizer2.Add(self.filter,1)
self.vbox.Add(hsizer1,proportion = 0,flag = wx.EXPAND)
self.vbox.Add(hsizer2,proportion = 0,flag = wx.EXPAND)
self.SetSizer(self.vbox)
self.Show()
self.OpenDir.SetValue("click to open directory")
def OnTextChanged(self, event):
def refresh():
wnd = self.filter
currentText = event.GetString()
while wnd:
print currentText
wnd.Layout()
print wnd.Layout()
wnd = wnd.GetParent()
self.filter.SetInsertionPoint(len(currentText))
self.filter.SetMark(len(currentText), len(self.choices))
self.filter.Refresh()
refresh()
event.Skip()
def OnChooseRoot(self, event):
self.dirname=""
dlg = wx.FileDialog(self, "choose a file to open", self.dirname,
"", "*.*", wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
self.filename = dlg.GetFilename()
self.dirname = dlg.GetDirectory()
self.pathname = dlg.GetPath()
self.f = open(os.path.join(self.dirname, self.filename), 'r')
self.text = self.f.read()
labeltop = self.dirname + '\\'
self.OpenDir.SetValue(labeltop + self.filename)
sources = [StringIO(self.text)]
for i, source in enumerate(sources):
c = list(csv.reader(source))
self.choices = [x[1] for x in c]
self.filter.SetItems(self.choices)
app = wx.App(redirect=False)
frame = MainFrame(None)
app.MainLoop()
I'm attempting to draw in a non-customized (I mean, simply creating an instance of the default form class, not an instance of a deriving class I can create) System.Windows.Forms.Form in F#.
I had created a custom form, but I didn't need nor want a new complex structure like that, so I removed it, and it simplified the code a lot; so much, that it stopped to show an image.
The problem must be in the function I created to draw, that is in another F# project. I've created it (function conect) to connect points in the order they are provided, unlike System.Drawing.Graphics.DrawLines, that draws lines between the points in some other order why haven't noticed yet (maybe right to left, top to bottom, as the points are represented).
Programa.fs relevant code snippet:
let pen = new Pen(brush = Brushes.Black, width = 1.0f)
let original =
([|new PointF(50.0f, 50.0f); new PointF(100.0f, 50.0f)|])
use form1 = new Form(Width = 400, Height = 400, Text = "Fractais (Teste - Windows Forms)")
form1.Paint.Add(
fun e -> // (1)
original
|> List.ofArray
|> Base.applyFractal 1uy Base.fractalFunc1
|> Base.conect e.Graphics pen)
If in the lambda expression instead of what's written there was e.Graphics.DrawLines(pen, original), it would draw a simple line between the points in the list.
Here's the troublemaker method, in Base.fs, across the solution:
let conect (gr:Graphics) (pen:Pen) (points:PointF list) =
let rec usefulFunc (gr:Graphics) (pen:Pen) (points:PointF list) prevPoint =
match points with
| [] -> ()
| point :: remainings ->
gr.DrawLine (pen, prevPoint, point)
usefulFunc gr caneta remainings.Tail remainings.Head
usefulFunc gr pen points.Tail points.Head
And the called (from the form initialization snippet) and relevant methods' signatures, in Base.fsi (I could give you all of the full methods' implementation, but it would take a lot of space, and this is probably for you already becoming a long question to read):
val fractalFunc1 : points:PointF list -> PointF list
val applyFractal : stepNumber:byte -> fractalFunc:(PointF list -> PointF list) -> points:PointF list -> PointF list
val conect : gr:Graphics -> pen:Pen -> points:PointF list -> unit
For this specific problem, my search results were none. I'd like to know how can I make the function conect work.
Thanks in advance.
You have one error in conectar.
fUtil gr caneta resto.Tail resto.Head
Should be
fUtil gr caneta resto ponto
You're already matching the head and tail inside of the match statement.
The following code draws a line for me. I didn't have to modify much.
open System.Drawing
open System.Windows.Forms
let caneta = new Pen(brush = Brushes.Black, width = 1.0f)
let original =
([|new PointF(50.0f, 50.0f); new PointF(100.0f, 50.0f)|])
let form1 = new Form(Width = 400, Height = 400, Text = "Fractais (Teste - Windows Forms)")
let conectar (gr:Graphics) (caneta:Pen) (pontos:PointF list) =
let rec fUtil (gr:Graphics) (caneta:Pen) (pontos:PointF list) pontoAnt =
match pontos with
| [] -> ()
| ponto :: resto ->
gr.DrawLine (caneta, pontoAnt, ponto)
fUtil gr caneta resto ponto
fUtil gr caneta pontos.Tail pontos.Head
form1.Paint.Add(
fun e -> // (1)
original
|> List.ofArray
//|> aplicFractal 1uy Base.funcFractal1
|> conectar e.Graphics caneta)
form1.Show()
Application.Run(form1)