PDA

View Full Version : QPainter and refresh window



Atikae
17th February 2009, 22:38
I use PyQt4 and I note that when I change something on a QPainter (example : when I draw a point at different positions), I need to move my mouse (or do some other actions) ON the window if I want to see the modifications.

Exemple :

from socket import WiiSocket
from general import main
import threading
import sys
from PyQt4 import QtGui
import time


class WiiButtons:
buttons = {"Up" : False,
"Down" : False,
"Left" : False,
"Right" : False,
"Plus" : False,
"Minus" : False,
"Home" : False,
"One" : False,
"Two" : False,
"A" : False,
"B" : False
}

def parse(self, data):
if data[:5] != "A1 30":
return

data = data[6:].split()
self.buttons["Left"] = bool(int(data[0],16)&0x01)
self.buttons["Right"] = bool(int(data[0],16)&0x02)
self.buttons["Down"] = bool(int(data[0],16)&0x04)
self.buttons["Up"] = bool(int(data[0],16)&0x08)
self.buttons["Plus"] = bool(int(data[0],16)&0x10)
self.buttons["Minus"] = bool(int(data[1],16)&0x10)
self.buttons["Home"] = bool(int(data[1],16)&0x80)
self.buttons["One"] = bool(int(data[1],16)&0x02)
self.buttons["Two"] = bool(int(data[1],16)&0x01)
self.buttons["A"] = bool(int(data[1],16)&0x08)
self.buttons["B"] = bool(int(data[1],16)&0x04)

def current(self):
return self.buttons


if __name__ == "__main__":

class MyWidget(QtGui.QWidget):

x = 0
y = 0

def paintEvent(self, QPaintEvent):
painter = QtGui.QPainter(self)
painter.drawPoint(self.x, self.y)


def get_info(handler, widget):
buttons = WiiButtons()

x = 300
y = 300

while handler.state == True:

data = handler.receive(32)
if len(data):
buttons.parse(data)
if buttons.current()["Up"]:
widget.y -= 1
widget.repaint()
print "Up"
if buttons.current()["Down"]:
widget.y += 1
widget.repaint()
print "Down"
if buttons.current()["Left"]:
widget.x -= 1
widget.repaint()
print "Left"
if buttons.current()["Right"]:
widget.x += 1
widget.repaint()
print "Right"


wiimote = main()

app = QtGui.QApplication(sys.argv)
widget = MyWidget()
widget.resize(600, 600)
window = QtGui.QMainWindow()
window.setCentralWidget(widget)
window.show()
thread = threading.Thread(None, get_info, None, (wiimote,widget))
thread.start()
app.exec_()



I guess there is a function or other things for refresh window automatically.

Thanks.

wysota
17th February 2009, 23:11
You are starving the event loop with your while loop.

http://doc.trolltech.com/qq/qq27-responsive-guis.html

Hmm... wait... you are doing that from another thread which is even worse. You musn't call methods of QWidget from worker threads. You don't even need that thread at all. Read the article from the link above to see some of the possible alternatives.

Atikae
18th February 2009, 10:03
Nice =D
I just add

QtCore.QCoreApplication.postEvent(widget, QtCore.QEvent(QtCore.QEvent.Move))
QtCore.QCoreApplication.processEvents()

Unless it's doesn't work only with processEvents() (I think it need some event to refresh window ;) )
Thanks.

wysota
18th February 2009, 12:45
Why complicate things so much? The event you post is not needed for anything. Just use QWidget::move() and that's it. No need for threads, no need for repaints.