PyQt - clear widget for redraw

Peter nospamjynyl at yahoo.co.nz
Tue Aug 3 21:19:06 CEST 2004


Diez B. Roggisch wrote:
> Maybe it helps to put your sleep not in the drawing code, but between the
> arrival of different data sets to draw, thus limiting the redraws to an
> amount of lets say 10/s.

Yes - tried that, but gives incomplete draw / flicker.
 
> If you'd fill us in with some more details, the suggestions might be
> better. And I think it would be worth asking these qustions on the PyKDE
> list Jim has mentioned - I'm also there :)

More details:
the idea is to provide a graphics demo of sort algorithms for my 13 year old
son.  A number of lines of differring lengths are shown on the screen, and
you can watch as these are sorted, step by step.  So you can see the
difference between bubble sort, ripple sort, etc.
Code copied below.
Improving the smoothness of the display is the main thing I'm after.
Also, how can I write the counters to the form?  It uses the LCD widget now,
but there must be another way.

TIA

Peter

-- sort1.py ---
#!/usr/bin/python
#
# demo of sort algorithms, using PyQt

import sys, random, time
from qt import *

from frmtest import frmTest

class dlgForm(frmTest):

    def __init__(self, parent=None):
        frmTest.__init__(self, parent)
        self.connect(self.cmdQuit, SIGNAL("clicked()"),self,
SLOT("close()"))
        self.connect(self.cmd2, SIGNAL("clicked()"), self.reshuffle)
        self.connect(self.cmdSort, SIGNAL("clicked()"), self.sort1)
        self.connect(self.cmdBubble, SIGNAL("clicked()"), self.bubble)
        self.connect(self.cmdRipple, SIGNAL("clicked()"), self.ripple)
        self.connect(self.cmdShell, SIGNAL("clicked()"), self.shells)
        self.refresh()

    def reshuffle(self):
        global cComp, cSwap, b1, b2, r1, r2
        cComp, cSwap, b1, b2 = [0,0,0,len(l1)]
        random.shuffle(l1)
        self.refresh()
    
    def sort1(self):
        global cComp, cSwap, b1, b2, r1, r2
        cComp, cSwap, b1, b2 = [0,0,0,len(l1)]
        l1.sort()
        self.refresh()
    
    def bubble(self):            # simple bubble sort
        global cComp, cSwap, b1, b2, r1, r2
        cComp, cSwap, b1, b2 = [0,0,0,len(l1)]
        b1 = 0
        b2 = len(l1)
        for i in range(len(l1)):
            b2 = len(l1) - i
            for j in range(b2-1):
                cComp = cComp + 1
                r1 = j
                r2 = j+1
                if l1[r1] > l1[r2]:
                    cSwap = cSwap + 1
                    l1[r1], l1[r2] = [l1[r2], l1[r1]]
                self.refresh()
                time.sleep(0.02)
    
    def ripple(self):
        global cComp, cSwap, b1, b2, r1, r2
        cComp, cSwap, b1, b2 = [0,0,0,len(l1)]
        bDone =1
        while bDone:
            bDone = 0
            for j in range(b1,b2-1):
                cComp = cComp + 1
                r1 = j
                r2 = j + 1
                if l1[r1] > l1[r2]:
                    cSwap = cSwap + 1
                    bDone = 1
                    l1[r1], l1[r2] = [l1[r2], l1[r1]]
                self.refresh()
                time.sleep(0.01)
            b2 = b2 - 1
            for j in range(b2,b1,-1):
                cComp = cComp + 1
                r1 = j - 1
                r2 = j
                if l1[r1] > l1[r2]:
                    cSwap = cSwap + 1
                    bDone = 1
                    l1[r1], l1[r2] = [l1[r2], l1[r1]]
                self.refresh()
                time.sleep(0.01)
            b1 = b1 + 1
        self.refresh()
    
    def shells(self):
        global cComp, cSwap, b1, b2, r1, r2
        cComp, cSwap, b1, b2 = [0,0, 0, len(l1)]
        bDone = 1
        span = 64
        while bDone:
            bDone = 0
            for i in range(b1,b2-span):
                r1 = i
                r2 = i + span
                cComp = cComp + 1
                if l1[r1] > l1[r2]:
                    cSwap = cSwap + 1
                    bDone = 1
                    l1[r1], l1[r2] = [l1[r2], l1[r1]]
                self.refresh()
                time.sleep(0.01)
            
            if not bDone:     # if no changes that sweep, exit
                break
            bDone = 0
            if span > 1:
                span = int(span/2)
                
            for i in range(b2-1,b1+span,-1):
                r1 = i - span
                r2 = i
                cComp = cComp + 1
                if l1[r1] > l1[r2]:
                    cSwap = cSwap + 1
                    bDone = 1
                    l1[r1], l1[r2] = [l1[r2], l1[r1]]
                self.refresh()
                time.sleep(0.01)
            if span > 1:
                span = int(span/2)
        self.refresh()
    
    def refresh(self):
        self.LCDcount.display('%3d' % cComp)    # update counters
        self.LCDswap.display('%3d' % cSwap)
        self.frame4.erase()                      # clear any old lines
        p = QPainter(self.frame4)
        mar = self.frame4.width()/100            # margin
        vsp = 2                                  # vertical spacing
        hrz = (self.frame4.width()-2*mar)/100    # horizontal scalar
        p.setPen(QColor("black"))
        for i in range(100):
            p.drawLine(mar,mar+vsp*i,hrz*(l1[i]+1),mar+vsp*i)
        p.setPen(QColor("blue"))
        p.drawLine(mar,mar+vsp*b1-1,hrz*100,mar+vsp*b1-1)
        p.drawLine(mar,mar+vsp*b2-1,hrz*100,mar+vsp*b2-1)
        p.setPen(QColor("red"))
        p.drawLine(mar,mar+vsp*r1+1,hrz*100,mar+vsp*r1+1)
        p.drawLine(mar,mar+vsp*r2+1,hrz*100,mar+vsp*r2+1)

if __name__ == '__main__':
    l1 = range(100)   # numbers 0 to 99
    b1 = 0            # blue line 1
    b2 = 100          # blue line 2
    r1 = 1            # red line 1
    r2 = 1            # red line 2
    cComp = 0         # count of compares
    cSwap = 0         # count of swaps
    app = QApplication(sys.argv)
    QObject.connect(app, SIGNAL('lastWindowClosed()'),
                    app, SLOT('quit()'))
    win = dlgForm()
    app.setMainWidget(win)
    win.show()
    app.exec_loop()
-------------------------------------------------------


-------- frmtest.py  --------------------------
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'frmtest.ui'
#
# Created: Sun Aug 1 15:55:11 2004
#      by: The PyQt User Interface Compiler (pyuic) 3.8
#
# WARNING! All changes made in this file will be lost!

from qt import *

class frmTest(QMainWindow):
    def __init__(self,parent = None,name = None,fl = 0):
        QMainWindow.__init__(self,parent,name,fl)
        self.statusBar()

        if not name:
            self.setName("frmTest")

        self.setCentralWidget(QWidget(self,"qt_central_widget"))

        self.frame4 = QFrame(self.centralWidget(),"frame4")
        self.frame4.setGeometry(QRect(40,109,441,210))
        self.frame4.setMinimumSize(QSize(440,210))
        self.frame4.setFrameShape(QFrame.StyledPanel)
        self.frame4.setFrameShadow(QFrame.Raised)
        self.frame4.setMargin(1)

        self.cmd2 = QPushButton(self.centralWidget(),"cmd2")
        self.cmd2.setGeometry(QRect(210,330,100,50))

        self.cmdSort = QPushButton(self.centralWidget(),"cmdSort")
        self.cmdSort.setGeometry(QRect(350,330,100,50))

        self.cmdQuit = QPushButton(self.centralWidget(),"cmdQuit")
        self.cmdQuit.setGeometry(QRect(70,330,100,50))

        self.txtHello = QLabel(self.centralWidget(),"txtHello")
        self.txtHello.setGeometry(QRect(50,20,450,76))
        txtHello_font = QFont(self.txtHello.font())
        txtHello_font.setPointSize(48)
        self.txtHello.setFont(txtHello_font)
        self.txtHello.setAlignment(QLabel.AlignCenter)

        self.cmdBubble = QPushButton(self.centralWidget(),"cmdBubble")
        self.cmdBubble.setGeometry(QRect(500,109,80,40))

        self.cmdRipple = QPushButton(self.centralWidget(),"cmdRipple")
        self.cmdRipple.setGeometry(QRect(500,160,80,40))

        self.cmdShell = QPushButton(self.centralWidget(),"cmdShell")
        self.cmdShell.setGeometry(QRect(500,210,80,40))

        self.txtCopyright = QLabel(self.centralWidget(),"txtCopyright")
        self.txtCopyright.setGeometry(QRect(40,380,400,21))

        self.LCDswap = QLCDNumber(self.centralWidget(),"LCDswap")
        self.LCDswap.setGeometry(QRect(490,370,91,31))
        self.LCDswap.setSegmentStyle(QLCDNumber.Flat)

        self.LCDcount = QLCDNumber(self.centralWidget(),"LCDcount")
        self.LCDcount.setGeometry(QRect(490,329,91,31))
        self.LCDcount.setMode(QLCDNumber.Dec)
        self.LCDcount.setSegmentStyle(QLCDNumber.Flat)

        self.languageChange()

        self.resize(QSize(603,438).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)

    def languageChange(self):
        self.setCaption(self.__tr("test form"))
        self.cmd2.setText(self.__tr("Reshuffle"))
        self.cmdSort.setText(self.__tr("Sort"))
        self.cmdQuit.setText(self.__tr("Quit"))
        self.txtHello.setText(self.__tr("Sort Demo"))
        self.cmdBubble.setText(self.__tr("Bubble"))
        self.cmdRipple.setText(self.__tr("Ripple"))
        self.cmdShell.setText(self.__tr("Shell"))
        self.txtCopyright.setText(self.__tr("Copyright 2004 GPL Peter"))

    def __tr(self,s,c = None):
        return qApp.translate("frmTest",s,c)
---------------------------------------------------------








More information about the Python-list mailing list