2013-03-29 34 views
0

我有一个画布小部件的GUI。所以我需要用点来感受这幅画布。问题是我需要创建一个独立的进程来运行GUI,因为点的(x,y)是从其他类生成的。所以我无法弄清楚如何从paintEvent以外画出这个点,或者我如何(如果有必要)再次触发paintEvent .-。绘画没有paintEvent

编辑:

我需要运行一个遗传算法,并获得每一代的健身结果,并表示它在画布区域为折线图!但我需要在飞行中绘制/绘制结果。

因此,每次GA完成一个健身周期,我需要将这个结果发送到画布区域。

我从http://zetcode.com/tutorials/pyqt4/drawing/得到了这个示例代码并修改了一下!

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

""" 
ZetCode PyQt4 tutorial 

In the example, we draw randomly 1000 red points 
on the window. 

author: Jan Bodnar 
website: zetcode.com 
last edited: September 2011 
""" 

import sys, random , time 
from multiprocessing import Process 
from PyQt4 import QtGui, QtCore 

class Example(QtGui.QWidget): 

    def status(self , text): 

     print '[GUI] ', text 

    def __init__(self): 

     super(Example, self).__init__() 

     self.initUI() 

    def initUI(self):  

     self.status('init ui') 

     self.setGeometry(300, 300, 280, 170) 
     self.setWindowTitle('Points') 

     self.status('showing widgets') 

     self.show() 

    def paintEvent(self, e): 

     self.status('playing with types : '+str(e)) 

     self.status('paint event was called') 

     qp = QtGui.QPainter() 
     qp.begin(self) 

     #self.drawPoints(qp) 

     #self.drawRectangles(qp) 

     self.draw_all_axis(qp, 300) 

     self.draw_dot(20, 20) 

     qp.end() 

    def draw_all_axis(self , qp , length): 

     self.draw_x_axis(qp , length) 
     self.draw_y_axis(qp , length) 

    def draw_x_axis(self , qp , length): 

     color = QtGui.QColor(0, 0, 0) 
     color.setNamedColor('#d49EBD8') 
     qp.setPen(color) 

     qp.setBrush(QtGui.QColor(73, 235, 216)) 
     qp.drawLine(10 , length , length , length) 

    def draw_y_axis(self , qp , length): 

     color = QtGui.QColor(0, 0, 0) 
     color.setNamedColor('#d49EBD8') 
     qp.setPen(color) 

     qp.setBrush(QtGui.QColor(73, 235, 216)) 
     qp.drawLine(10, 10, 10, length) 

    def draw_dot(self , x , y): 

     qp = QtGui.QPainter() 
     qp.begin(self) 

     color = QtGui.QColor(0, 0, 0) 
     color.setNamedColor('#d4d4d4') 
     qp.setPen(color) 

     qp.setBrush(QtGui.QColor(200, 0, 0)) 
     qp.drawRect(x , y , x + 0.25, y + 0.25) 

    def drawPoints(self, qp): 

     qp.setPen(QtCore.Qt.red) 
     size = self.size() 

     for i in range(1000): 

      x = random.randint(1, size.width()-1) 

      y = random.randint(1, size.height()-1) 

      qp.drawPoint(x, y)  

    def drawRectangles(self, qp): 

     color = QtGui.QColor(0, 0, 0) 
     color.setNamedColor('#d4d4d4') 
     qp.setPen(color) 

     qp.setBrush(QtGui.QColor(200, 0, 0)) 
     qp.drawRect(10, 15, 90, 60) 

     qp.setBrush(QtGui.QColor(255, 80, 0, 160)) 
     qp.drawRect(130, 15, 90, 60) 

     qp.setBrush(QtGui.QColor(25, 0, 90, 200)) 
     qp.drawRect(250, 15, 90, 60)  

def external_dot_drawer(main_window): 


    for i in range(20, 100): 

     main_window.draw_dot(i , i) 


def main(): 

    print 'launching main window obj as app' 
    sys.exit(app.exec_()) 
    print 'done!' 

if __name__ == '__main__': 

    print 'loading application abstraction' 
    app = QtGui.QApplication(sys.argv) 

    print 'building main window obj' 
    gui = Example() 

    print 'preparing to launch window as a separated process' 
    p_main = Process(name='window' , target=main , args=() ) 

    print 'running new process' 
    p_main.start() 

    time.sleep(3) 

    print 'trying to triggering paintEvent' 
    p_external_dot_drawer = Process(name='extern_dot_drawer' , target=external_dot_drawer , args=(gui)) 
+1

*为什么*你想使用多处理?您提供的代码完全没有理由使用它。无论如何,你**不能**从多个过程调用GUI,你只需避免这种情况。如果你给了我们一些背景,我们可能会给你一些选择。 – Bakuriu

回答

0

用于调度paintEvent的正确方法是使用QWidget.update()。

我也建议使用任何现有的python绘图库,而不是自己写。 PyQtGraph有一些不错的多进程功能:

import pyqtgraph as pg 
app = pg.QtGui.QApplication([]) 
import pyqtgraph.multiprocess as mp 

## start child process 
proc = mp.QtProcess() 

## import pyqtgraph in the child process, create a plot window there 
remotepg = proc._import('pyqtgraph') 
win = remotepg.plot() 

## create a scatter plot 
plot = win.plot([1,4,2,3], [4,6,3,4], pen=None, symbol='o') 

## ..after some processing, update the plot data 
plot.setData(x=[1,2,3,4], y=[5,7,2,3])