添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've a GUI with a canvas widget. So i need to feel this canvas with points. The problem is that i need to create a separated process to run GUI because the (x,y) for the points are generated from other class. So i cant figure out how can i draw this points from outside of the paintEvent or how can i (if necessary) trigger the paintEvent again .-.

edit :

I need to run a genetic algorithm and get the fitness result of each generation and represent it on the canvas area as a line chart! But i need to plot/draw the results on the fly.

So every time the GA completes a fitness cycle i need to send this results to the canvas area.

I've got this example code from http://zetcode.com/tutorials/pyqt4/drawing/ and modified a little!

#!/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 ) )
                Why do you want to use multiprocessing? The code you provided has absolutely no reason to use it. Anyway, you cannot call the GUI from multiple processes you simply have to avoid that situation. If you gave us some context we may give you some alternatives.
– Bakuriu
                Mar 29, 2013 at 15:36

The correct way to schedule a call to paintEvent is with QWidget.update().

I would also recommend using any of the existing python plotting libraries rather than writing your own. PyQtGraph has some nice multi-process features:

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])
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.