• 締切済み

Pythonでキーが押されたことを判定したい

Python初心者です。Pythonでキー入力の値を変数keyとして取り出したいのですが、上手くいきません。 グローバル関数がわかっていないのかと思いますが直し方がわかりません。 最終的に37行目のprint(key)でkeyの値を取り出したいのですがどうすればよいですか。 # -*- coding: utf8 -*- import tkinter as tk import winsound root = tk.Tk() frame = tk.Canvas(root, width=800, height=600) pimg = tk.PhotoImage(file="wall.png") frame.place(x=0, y=0) frame.create_image(400, 300, image=pimg) imgA = tk.PhotoImage(file = 'pressed_A.png') imgB = tk.PhotoImage(file = 'Pressed_B.png') def keyA(event): global key key="A" frame.place(x=0, y=0) frame.create_image(320, 220, image=imgA, tag="illust") root.update() winsound.PlaySound("pressed_A.wav", winsound.SND_FILENAME) def keyB(event): global key key="B" frame.place(x=0, y=0) frame.create_image(320, 220, image=imgB, tag="illust") root.update() winsound.PlaySound("pressed_B.wav", winsound.SND_FILENAME) frame.bind("a", keyA) frame.focus_set() frame.pack() frame.bind("b", keyB) frame.focus_set() frame.pack() print(key) root.mainloop()

  • Python
  • 回答数1
  • ありがとう数2

みんなの回答

  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.1

 Pythonは、インデントが命なので、ここでソースを出すのは難しいですね。  def keyAと、def keyBの内容は、その後のwinsoundまで。他は、インデント無しの前提で、読んでみます。  関数定義と、メイン実行が入り交じっていますが、このプログラムは、最後の行のroot.mainloop()まで、一気に実行が進みます。その後、プログラムは、その一生をmainloopで過ごします。mainloopでは、各イベントの監視を行い、登録されたイベントがあれば、イベントハンドラを呼び出します。例えば、frame.bind("a",keyA)がその例です。aキーが押された時、keyAを呼び出すわけです。  さて、問題のprint(key)ですが、これ、最初の実行時に、root.mainloop()に到達する直前に一回だけ呼ばれます。その後、2度とここが実行されることはありません。  これが、問題の本質です。  多分、最初のprint(key)の呼び出し時点では、何もキーは押されていないでしょうし、何より、イベントの監視が始まっていませんからその時点では、例えキーが押されていても反応はありません。よって、イベントハンドラは実行されませんから、keyの中身はありません。  そして、mainloopの呼び出しでイベントの監視が始まった後は、もう、二度とこのprint文に制御が渡ることはありません。  というわけで、このprint文が意味のある出力をすることはありません。  定期的にprint(key)をしたいのであれば、タイマーイベントを作るなどの工夫が必要です。

関連するQ&A

  • javaで作成したゲーム→android用に変換

    お世話になっています。 前回こちらで、 1~25までの順番にタッチしていくというゲームのjavaのソースコードを教えて頂きました。 今回お聞きしたい内容が そのゲームに (1)秒単位のタイマーを付け、25個目の数字を押したらカウント終了 (2)androidアプリとして使用できるように変換 としようとしているのですが、いろいろと変換しなければいけないみたいで、 どちらもなかなかうまくいきません。 前回教えて頂いたコード import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; class MainFrame extends JFrame { private static final long serialVersionUID = 1L; private List<NumberdButton> numbers = new ArrayList<NumberdButton>(); private GridLayout grid = new GridLayout(5, 5); private boolean[] pressed = new boolean[5 * 5 + 1]; public MainFrame(String name) { super(name); setResizable(false); } public void setButtons(final Container pane) { initPressed(); initNumbers(); final JPanel p = new JPanel(grid); for (final NumberdButton b : numbers) { p.add(b); b.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (pressed[b.getNumber() - 1]) { b.setIcon(new ImageIcon("" + numbers + "_off.png")); b.setEnabled(false); pressed[b.getNumber()] = true; } } }); } pane.add(p, BorderLayout.CENTER); } private void initNumbers() { for (int i = 1; i < 26; i++) { numbers.add(new NumberdButton(i)); } Collections.shuffle(numbers); } private void initPressed() { for (int i = 0; i < pressed.length; i++) pressed[i] = false; pressed[0] = true; } public static void create(String name) { MainFrame frame = new MainFrame(name); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.setButtons(frame.getContentPane()); frame.pack(); frame.setVisible(true); } } class NumberdButton extends JButton { private static final long serialVersionUID = 1L; private final int number; public NumberdButton(int number) { super(new ImageIcon("" + number + ".png")); this.number = number; } public int getNumber() { return number; } } public class pressbuttontoorder { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { MainFrame.create("PressButtonToOrder"); } }); } } androidのレイアウトはTableLayoutとtableRowでボタンを配置すればいいのかなと思い 配置しました。 TableLayout <TableRow1 <Button1~5 <TableRow2 <Button6~10 という風に25個ボタンを配置しています。 行き詰まっております。 どなたかやり方やコード等、教えて頂けたらありがたいです。 ご教授よろしくお願いします。

    • ベストアンサー
    • Java
  • Ruby/SDLの処理を早くしたい

    Ruby/SDLを使ってブロック崩しを制作しているのですが画面いっぱいにブロックを並べたら処理が落ちて困っています。なにか軽くする方法を教えていただけないでしょうか?お願いします。 ソース抜粋 重要そうなところだけ抜粋してみました require "sdl" require "lib/fpstimer" SCREEN_W = 640 SCREEN_H = 480 def load_image(fname) image = SDL::Surface.load(fname) image.set_color_key(SDL::SRCCOLORKEY, [255, 255, 0]) image end SDL.init(SDL::INIT_EVERYTHING) screen=SDL.set_video_mode(SCREEN_W, SCREEN_H, 16,SDL::SWSURFACE) ball = load_image("image/ball.png") bar = load_image("image/bar.png") block = [load_image("image/block1.png"), load_image("image/block2.png"), (略します) load_image("image/block9.png")] board =[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], (略します 25*32) [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]] loop do screen.fillRect 0, 0, 640, 480, [ 0, 0, 0 ] speedX = 5 if speedX > 5 speedY = 5 if speedY > 5 speedX = -5 if speedX < -5 speedY = -5 if speedY < -5 SDL::Key.scan if SDL::Key.press?(SDL::Key::SPACE) barX -= 12 if SDL::Key.press?(SDL::Key::LEFT) barX += 12 if SDL::Key.press?(SDL::Key::RIGHT) else barX -= 8 if SDL::Key.press?(SDL::Key::LEFT) barX += 8 if SDL::Key.press?(SDL::Key::RIGHT) end if ballenterflag == 0 if SDL::Key.press?(SDL::Key::RETURN) ballenterflag = 1 end if SDL::Key.press?(SDL::Key::LEFT) if SDL::Key.press?(SDL::Key::RETURN) ballenterflag = 2 end end end #バーとボールの判定 if fallball == 0 if ballX + 6< barX + 96 && ballX + 6 > barX && ballY+ 6 > barY - 2 && ballY + 6 < barY + 12 + 2 # 周りにヒット if SDL::Key.press?(SDL::Key::LEFT) if speedX >= 0 && speedY >= 0 speedX = speedX / 1.2 speedY = speedY *1.2 elsif speedX < 0 && speedY > 0 speedX = speedX * 1.2 speedY = speedY / 1.2 end elsif SDL::Key.press?(SDL::Key::RIGHT) if speedX >= 0 && speedY >= 0 speedX = speedX * 1.2 speedY = speedY / 1.2 elsif speedX < 0 && speedY > 0 speedX = speedX / 1.2 speedY = speedY * 1.2 end end speedY = -speedY if ballX + 6< barX + 52 && ballX + 6 > barX + 44 && ballY+ 6 > barY - 2 && ballY + 6 < barY + 12 + 2 #真ん中ヒット kantuu = 1 elsif kantuu = 0 scoreplus = 200 end fallball = 1 #1ならボールを跳ね返さない end end for i in 0..25 for j in 0..32 #高さ if board[j][i] == 1 screen.put(block[0], blockX+i*24, blockY+j*12) elsif board[j][i] == 2 screen.put(block[1], blockX+i*24, blockY+j*12) 略します 1~10です elsif board[j][i] == 10 screen.put(block[9], blockX+i*24, blockY+j*12) end if board[j][i] != 0 if (ballX + 6 > blockX + i*24 && ballX + 6 < blockX + i*24 +24) && ((ballY + 6 > blockY + j*12 -3 && ballY + 6 < blockY + j*12 + 3) || (ballY + 6 > blockY + j*12 + 12 -3 && ballY + 6 < blockY + j*12 +12 + 3)) if kantuu == 0 speedY = -speedY end board[j][i] = 0 score += scoreplus scoreplus += 50 elsif (ballY + 6 > blockY + j*12 && ballY + 6 < blockY + j*12 + 12) && ((ballX + 6 > blockX + i*24 -2 && ballX + 6 < blockY + i*24 +3) || (ballX + 6 > blockX + i*24 + 24 -3 && ballX + 6 < blockY + i*24 +24 +2)) if kantuu == 0 speedX = -speedX end board[j][i] = 0 score += scoreplus scoreplus += 50 end end end end screen.put(ball, ballX, ballY) timer.wait_frame do screen.update_rect(0, 0, 0, 0) end end

  • キー(調号)を判定するソフトってないでしょうか?

    wavとかmp3の音声ファイルからキー(調号)を判定するソフトは無いでしょうか? midiからだとあるみたいなのですが…。(TMIDI Player) また、たとえば、AmとCのどちらかは判定できなくてもいいです。 wavからmidiに変換する聞き耳ソフト(採譜の達人)なんていうのも実在するので、なんか、ありそうな気もするのですが…。 海外のものでも良いので、どこかに無いでしょうか? あと、ソフトに頼らない方法でもいい方法があったら教えて下さい。 自分は、鍵盤で全部音をたたいてみてドの位置を探しているのですが、もっと良い方法があったら教えて下さい。 っていうか、12種類の音階のファイルを作っておいて、それを個別に合わせて聞いてみるスクリプトみたいのを組んでおいて、合うのを探すなんていう変な方法(笑)も考えてみちゃったりするのですが、真剣に、なんかいい方法無いでしょうか?

  • pythonをhtmlに埋め込みたい

    htmlにpythonを埋め込みたいのですが、 ローカル環境でhtmlを読み込んでもpython部分が起動してくれません。 なにか特別な環境を用意する必要があるのでしょうか? また、そういった内容を書かれているHPがありましたら教えて頂けないでしょうか。 よろしくお願いします。

  • python

    pythonが使えません 動作環境 windows7 pythonバージョン 2.7.6 どうかおしえてください。

  • 難しいかもしれませんが、Pythonについて

    以下の英英辞書のオンラインサイトで、複数の単語の定義だけを一箇所(例えばメモ帳など)にまとめるプログラミングは可能でしょうか? http://www.learnersdictionary.com/search/record 上のURLはrecordの定義ですが、欲しい部分は見出し語(ここではrec·ordから)その定義の最後の部分(ここでは~ happened last week.)までです。そのあいだの部分すべてをメモ帳などにコピペして、次の別の単語の定義をメモ帳にコピペして、さらに次にというのようなプログラミングが欲しいのです。 ちなみに、私の手持ちのものは、約2万の調べたい英単語とそのURLです。また、その単語の中には、上記の英英辞書にのっていないものがあります(例えばqualtagh; http://www.learnersdictionary.com/search/qualtagh) 私はプログラミングはほんとどなにもしりませんので、できれば説明ではなくプログラムそのものを書いてくれるとありがたいです。

  • python3.6.5で

    sheet = wb.get_sheet_by_name('Sheet1') というコマンドをうつと以下のようなエラーが出ます。 Warning (from warnings module): File "__main__", line 1 DeprecationWarning: Call to deprecated function get_sheet_by_name (Use wb[sheetname]). アドバイスをいただけるとありがたいです。

  • Python

    今日からPythonを学び始めた、超初心者です! とっても初歩的な質問で申し訳ないのですが、私の周りで聞ける人がいないので、どなたか助けていただけると嬉しいです。 Pythonの条件分岐の式で、例えば、 score=100 if score = = 100 : print ('よくできました’) とあった場合、2つの=の間や、100と:、またprintと( のスペースは空けてはいけないというルールなのでしょうか? どこがスペースを空けてよくて、どこがダメなのかを知りたいです。 このような質問をすみません。 よろしくお願いいたします。

  • pythonについて

    pythonで質問です。 初心者です。 全くやったことかないです。 例えば、サイコロの目を予測するaiを作ったとしてどのような処理が行われているのですか? 予測するまでの挙動とかを教えてください。 また、代表的なaiのプログラムとその処理を簡単にでいいので教えてください。

  • python

    リストにa=['6581', '6581', '6584']とあるのですが、 重複する数字を1つだけ削除したいのですがどうしたらいいでしょうか。