質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Q&A

解決済

1回答

1423閲覧

python2.7 + pyqt4でprint文が実行されなくなる問題

TomokiUmino

総合スコア10

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

0グッド

0クリップ

投稿2015/10/08 06:33

現在、Python2.7とPyQt4を使用したGUIアプリケーションの作り方を学んでいます。
一通りチュートリアルを終えたので、簡単なゲームを作ってみようとコーディングをしていたのですが
print文が正常に実行されなくなるという問題が発生しました。

具体的には、keyPressEventで、キーの入力によって状態を変化させ、変更後の状態を出力するという処理の際に一回目に発生したイベントでは、値が出力されず、二回目に発生したイベントで2つの出力が行われるという現象です。

公式のドキュメントなどを参照しましたが、原因がわかりませんので、何方か教えていただければ幸いです。

以下コード

lang

1# -*- coding: utf-8 -*- 2 3import sys 4from PyQt4 import QtGui, QtCore 5 6class Tankdaze(QtGui.QWidget): 7 def __init__(self): 8 super(Tankdaze, self).__init__() 9 10 self.initUI() 11 12 def initUI(self): 13 14 #signalをコネクト 15 self.c = Communicate() 16 self.c.changeUI.connect(self.changeUI) 17 18 #スタート画面の生成 19 self.titleLabel = QtGui.QLabel(self) 20 titleImage = QtGui.QPixmap('Hydrangeas.jpg') 21 self.titleLabel.setPixmap(titleImage) 22 23 self.setGeometry(100, 100, 1024, 768) 24 self.setFixedSize(1024, 768) 25 self.show() 26 27 def changeUI(self): 28 self.titleLabel.hide() 29 30 imageLabel = QtGui.QLabel(self) 31 imageFromCam = QtGui.QPixmap('Jellyfish.jpg') 32 imageLabel.setPixmap(imageFromCam) 33 imageLabel.show() 34 35 #ゲーム残り時間 36 timer = QtGui.QLCDNumber(self) 37 timer.move(472, 10) 38 timer.resize(80, 80) 39 timer.show() 40 41 #残弾 42 bullet = QtGui.QLCDNumber(self) 43 bullet.move(894, 638) 44 bullet.resize(100, 100) 45 bullet.show() 46 47 #自機体力 48 myHP = QtGui.QProgressBar(self) 49 myHP.move(20, 20) 50 myHP.resize(400, 50) 51 myHP.show() 52 53 #敵機体力 54 enemyHP = QtGui.QProgressBar(self) 55 enemyHP.resize(400, 50) 56 enemyHP.move(644, 20) 57 enemyHP.show() 58 59 #待ちメッセージ 60 waitLabel = QtGui.QLabel(self) 61 waitLabel.setText(u'<font color = white size = 30>相手プレイヤーの準備を待っています</font>') 62 waitLabel.move(250, 650) 63 waitLabel.show() 64 65 #timerをセット 66 loopTimer = QtCore.QTimer() 67 loopTimer.timeout.connect(self.gameLoop) 68 loopTimer.start(1000) 69 70 #ここに、相手も準備ができているか確かめる処理を入れる 71 72 def keyPressEvent(self, e): 73 if e.key() == QtCore.Qt.Key_Space: 74 self.gameState = 'ready' 75 print 'current state is ' + self.gameState 76 self.c.changeUI.emit() 77 78 elif e.key() == QtCore.Qt.Key_A: 79 self.gameState = 'game' 80 print 'current state is ' + self.gameState 81 82 def gameLoop(self): 83 print 'hello' 84 85 86class Communicate(QtCore.QObject): 87 88 changeUI = QtCore.pyqtSignal() 89 90def main(): 91 app = QtGui.QApplication(sys.argv) 92 tankdaze = Tankdaze() 93 sys.exit(app.exec_()) 94 95if __name__ == '__main__': 96 main()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こちらで試した環境(win8.1/python2.7.6.9/PyQt4.8.7)では、
DOSプロンプトからスクリプトを実行したところ、
keyイベントのprint文は期待通りのタイミングで出力されました。
(画像ファイルがないためそのまま実行できなかったので、画像ファイルは空欄にして実行しました)

端末のバッファ内に出力されずに残っている等が考えられますが、
試しに、print文の直後に sys.stdout.flush() を呼び出してみるとどうでしょう?

後、タイマーのイベントで呼ばれると想定されてるprint文に関しては、
タイマーのオブジェクトが何処にも参照されていないため、changeUI を抜けた後に、
ガベレージコレクタにより自動的に破棄されてしまいます。helloは出力されていませんでした。

python

1loopTimer = QtCore.QTimer(self)

とすると、期待通り1秒間隔でgameloopを呼ぶタイマーを稼働出来ます。


print文の挙動は実行環境によっても動作が異なる可能性があります。

標準出力(Python内でsys.stdout)が他の場所に結び付けられている場合、
例えば、IDE等でデバッグ実行した場合等も変わってくるので、
実行環境の情報も併せて検索すると、類似の問題が見つかるかもしれません。

投稿2015/10/21 14:11

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomokiUmino

2015/10/25 07:52

回答ありがとうございました。 結局原因は、QTimerのコンストラクタにselfを渡していないことでした。 引数としてselfを渡したところ、因果関係はよくわかりませんが、print文が正しく動作するようになりました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問