2017-01-28 26 views
0

私は位置(0,0)の周りにカラーホイールを作成する、亀のプログラムをPythonで作成しました。ここにペーストビン:http://pastebin.com/xDyddfwaです。私ができることを望んでいるのは、ホイールのどこかをクリックすることができ、クリックした色が円の周りの何度にあるかを伝えることができます。だから、基本的に、デカルト座標の代わりに、私は円形グラフの座標が好きです。カラーホイールプログラムを実行した場合は、番号を入力するよう求められます。 6を入力すると、6色のホイールが描画されます。赤い部分が右下に表示されます。私はそれをクリックして0を取得したいと思います。次に、黄色をクリックすると、1などが得られます。また、どのように変数にその値を格納できますか? (私はonclick()を使って問題を抱えてきました)助けてください。クリックした位置の円グラフ座標を取得する方法

+1

常にコードと完全なエラーメッセージが表示されます。 – furas

+0

これを 'IDLE'の外側で実行するには' done() 'または' mainloop() 'が必要です。 'turtle'と' IDLE'は 'mainloop()'が必要な 'tkinter'を使います。 'IDLE'を実行すると' mainloop() 'が実行され、このコードは動作しますが、IDLEの外側では円を描きません。 – furas

+0

コードを読みやすくする: 'def'の前に空行を入れ、' if __name__'を空白にして、コンマの後にスペースを入れます。詳細:[PEP 8スタイルガイド(Pythonコード)]( – furas

答えて

0

onclick()は、タートルをクリックした場合にのみ機能します。すべてのクリックで機能を実行するには、onscreenclick(callback)を使用してください。それはあなたに(x,y)を与えるので、度でangleを計算してから、角度を正しい数値に変換する必要があります。それは色だけでなく、画面上のクリックごとに数値を計算するので理想的ではありません。

import turtle 
from turtle import * 
import colorsys 
import math 

def arch(radius, degree, width, colour): 
    color(colour) 
    pd() 
    begin_fill() 
    circle(radius, degree) 
    lt(90) 
    fd(width) 
    lt(90) 
    circle(-radius+width, degree) 
    lt(90) 
    fd(width) 
    lt(90) 
    end_fill() 
    pu() 
    circle(radius, degree) 
    pd() 

def start(): 
    pu() 
    rt(90) 
    fd(200) 
    lt(90) 

def startover(): 
    reset() 
    main() 

def get_number(x, y): 
    # inform function to use global variable 
    #global k 

    angle = 180 - math.degrees(math.atan2(x,y)) 

    angle %= 360 

    number = int(angle*k/360) 

    print('Pos:', x, y, 'Angle:', angle, 'Number:', number) 

def main(): 
    # Inform function to use global variable when you use `=` 
    # You will need this value in `get_number 
    global k 

    s = turtle.Screen() 
    #t = turtle.Turtle() 

    s.colormode(255) 
    tracer(False) 

    reset() 
    start() 

    k = int(numinput(""," How many colors?")) 

    colorlist = [] 

    for i in range(k): 
     colorlist.append(list(colorsys.hsv_to_rgb(i/k,1,255))) 

    print(colorlist) 

    for i in range(len(colorlist)): 
     for j in range(len(colorlist[i])): 
      colorlist[i][j] = int(colorlist[i][j]) 
     arch(200, 360/k, 100, (colorlist[i])) 

    onkey(startover, "a") 
    onscreenclick(get_number) 
    #listen() 

    done() 

if __name__ == "__main__": 
    main() 

EDIT:turtleはバックグラウンドでtkinterを使用し、tkinterがより強力である - すなわち。 arcpiesliceなどを描画する機能があり、キャンバス上のすべてのオブジェクトにマウスのクリックを割り当てることができます。

import turtle 
from turtle import * 
import colorsys 

def get_number(event, number): 
    #print('widget:', event.widget) 
    print('number:', number) 

def main(): 

    s = turtle.Screen() 

    s.colormode(255) 

    k = int(numinput("","How many colors?")) 

    colorlist = [] 

    for i in range(k): 
     color = colorsys.hsv_to_rgb(i/k,1,255) 
     color = (int(color[0]), int(color[1]), int(color[2])) 
     colorlist.append(color) 

    canvas = s.getcanvas() 

    for i in range(len(colorlist)): 
     # convert (255, 255, 255) into '#ffffff' 
     color = s._colorstr(colorlist[i]) 

     # create `arc` 
     part_id = canvas.create_arc(-200, -200, 200, 200, outline=color, start=(i*360/k)-90, extent=360/k, width=100, style='arc') 

     # assign button click to this part with `number` 
     canvas.tag_bind(part_id, '<Button>', lambda event, number=i:get_number(event, number)) 

    done() 

if __name__ == "__main__": 
    main() 

effbot.org:

+0

)これは問題のOPの説明に基づいて間違った結果をもたらすと思います6セグメントホイールでは、赤色は120度と180度ではなく0度と60度の間でなければなりません。これはコンソールに表示されるためです。また、ここにあるように、赤は数字0でなく2と3でなければなりません。 – cdlane

+0

あなたは正しいです:)私は色をチェックしなかった、私は上に0度で標準的なシステムを期待した。しかし、小さな変更を加えるとより効果的です。 – furas

+0

'tkinter'から' canvas'を使って例を追加しました。 – furas

0

The Tkinter Canvas Widgetは私が間違った結果を生成しながらOPのコードに基づいて、他の答えは、必要以上に複雑な問題になる感じ。以下は、ロジックを単純化し、正しい値を生成しようとした私の試みです(例えば、赤は0、黄色は1などです)。サークルを90度回転させて、数学のアライメントを良くしました。また、結果は、円の中心に印刷されています

from turtle import Turtle, Screen 
from colorsys import hsv_to_rgb 
import math 

FONT_SIZE = 18 
FONT = ('Arial', FONT_SIZE, 'normal') 

RADIUS = 200 
WIDTH = 100 

last_result =() # Also how could I store that value to a variable? 

def arch(radius, width, colorlist): 

    ''' Creates a color wheel around position (0,0) ''' 

    degree = 360/len(colorlist) 
    inner_radius = radius - width 

    turtle = Turtle(visible=False) 
    turtle.penup() 
    turtle.setx(radius) 
    turtle.setheading(90) 

    for color in colorlist: 
     turtle.color(color) 

     turtle.begin_fill() 
     turtle.circle(radius, degree) 
     position = turtle.position() 
     heading = turtle.heading() 
     turtle.left(90) 
     turtle.forward(width) 
     turtle.left(90) 
     turtle.circle(-inner_radius, degree) 
     turtle.end_fill() 

     turtle.setposition(position) 
     turtle.setheading(heading) 

def get_number(x, y, turtle, segments): 

    ''' 
    Click somewhere on the wheel, and be told how many degrees around the 
    circle the color you clicked. For a six-color wheel, if you click on 
    red, you get 0. If you click on yellow, you get 1, etc. 
    ''' 

    global last_result 

    if (RADIUS - WIDTH) ** 2 < x ** 2 + y ** 2 < RADIUS ** 2: 

     angle = math.degrees(math.atan2(y, x)) % 360 

     number = int(angle * segments/360) 

     turtle.undo() 
     turtle.write('{} ({:5.1f}\u00b0)'.format(number, angle), align='center', font=FONT) 

     last_result = (number, angle) 

def main(): 

    screen = Screen() 

    segments = int(screen.numinput('Color Wheel', 'How many colors?')) 

    colorlist = [hsv_to_rgb(i/segments, 1.0, 1.0) for i in range(segments)] 

    screen.tracer(False) 
    arch(RADIUS, WIDTH, colorlist) 
    screen.tracer(True) 

    magic_marker = Turtle(visible=False) 
    magic_marker.penup() 
    magic_marker.sety(-FONT_SIZE/2) 
    magic_marker.write('', align='center', font=FONT) 

    screen.onscreenclick(lambda x, y, t=magic_marker, s=segments: get_number(x, y, t, s)) 

    screen.mainloop() 

if __name__ == '__main__': 
    main() 

私は、コードを簡素化するために0.0〜1.0にカラーロジックを変更し、それだけであなたがカラーホイール自体をクリックしたときに応答行った、ではありません窓のどこにでもあります。

enter image description here

+0

ありがとう、私の質問に答えてくれてありがとう!私はそのようにプログラムすることができれば幸いです。そんなに助けて! –

+0

私は別の質問があります。 onscreenclick()はどのようにしてリスニングを止めることができますか?私は2回クリックして2つの数字を取得してから、他の機能に移動することができます。FTR:私は自分自身でそれを理解しようとしましたが、調査しましたが、いつものように、何も見つかりませんでした。それ以上の助けをいただければ幸いです。 –

+0

@JoshHendersonは、大部分のカメのイベントハンドラーと同様に、イベントハンドラーとして 'None'を指定すると、それをオフにします:' screen.onscreenclick(None) 'これは単純なウェブ検索で簡単に見つかるPythonのカメの文書に記述されています。 – cdlane

関連する問題