473,322 Members | 1,307 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

PyQt - clear widget for redraw


I want to draw some lines on a widget.
This works ok, but when I want to redraw, the old lines are still there.

How do I clear or refresh the widget, so I can draw a new set of lines?

Code snip below.

TIA

Peter
-------------------------
def paintLines(self, e):
p = QPainter(e)
mar = e.width()/100 # margin
vsp = 2 # vertical spacing
hrz = (e.width() - 2*mar)/100 # horizontal scalar
for i in range(100):
p.drawLine(mar,mar+vsp*i,hrz*(l1[i]+1),mar+vsp*i)
-------------------------

Jul 18 '05 #1
10 11640
Peter wrote:

I want to draw some lines on a widget.
This works ok, but when I want to redraw, the old lines are still there.

How do I clear or refresh the widget, so I can draw a new set of lines?


Call erase on your widget. Or redraw a rectangle yourself.
--
Regards,

Diez B. Roggisch
Jul 18 '05 #2
Diez B. Roggisch wrote:

Call erase on your widget. Or redraw a rectangle yourself.


Thanks, that works fine.
I just started using pyqt yesterday, and having trouble finding a reference
- most Qt stuff is written for c++.

Peter

Jul 18 '05 #3
Jim
Peter wrote:
Diez B. Roggisch wrote:

Call erase on your widget. Or redraw a rectangle yourself.


Thanks, that works fine.
I just started using pyqt yesterday, and having trouble finding a
reference - most Qt stuff is written for c++.

Peter


Boudewijn Rempt's book _GUI Programming with Python: QT Edition_
might be helpful. It's available online at:

http://www.opendocspublishing.com/pyqt/

You can also post your questions at:
PyKDE mailing list Py***@mats.imk.fraunhofer.de

sign up for the list at:
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde

There's also a PyQt wiki at:
http://www.diotavelli.net/PyQtWiki
(it's fairly new and a little light on content, but there's already some
good stuff there).
Jim

Jul 18 '05 #4
Peter wrote:
Thanks, that works fine.
I just started using pyqt yesterday, and having trouble finding a
reference - most Qt stuff is written for c++.


The neat thing on pyqt is that usually you can directly translate c++
examples to python. So there is no need to have a separate documentation
and other resources. The erase I looked up in the qt standard
documentation.

--
Regards,

Diez B. Roggisch
Jul 18 '05 #5
Diez B. Roggisch wrote:
Peter wrote:
Thanks, that works fine.
I just started using pyqt yesterday, and having trouble finding a
reference - most Qt stuff is written for c++.

The neat thing on pyqt is that usually you can directly translate c++
examples to python. So there is no need to have a separate documentation
and other resources. The erase I looked up in the qt standard
documentation.


Thanks
(and thanks to Jim for his response, too)

What I'm drawing is a series of lines (like a horizontal bar chart) and it
is updated several times a second. The problem is that it goes too fast.
I tried the time.sleep() function, but then it doesn't draw properly. It
seems to draw only part of the chart each time, and flickers.

Is there some way to make the display smoother?

TIA

Peter

Jul 18 '05 #6
> What I'm drawing is a series of lines (like a horizontal bar chart) and it
is updated several times a second. The problem is that it goes too fast.
I tried the time.sleep() function, but then it doesn't draw properly. It
seems to draw only part of the chart each time, and flickers.


Usually there is no "to fast" in graphics - so I've got to admit I'm not
sure what you are talking about.

Where does the data to draw come from, and how fast is it actually coming? A
flickering sensation usually stems from the redrawing done so fast it
interfers with the vertical retrace.

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.

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

--
Regards,

Diez B. Roggisch
Jul 18 '05 #7
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_wid get"))

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.minimum SizeHint()))
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)
---------------------------------------------------------

Jul 18 '05 #8
On Tuesday 03 August 2004 8:19 pm, Peter wrote:
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.


There are lots of standard graphics techniques for eliminating flicker when
drawing that you can exploit with PyQt. Double buffering for example - draw
to a QPixmap and then blit it to the QWidget.

Phil
Jul 18 '05 #9
Peter wrote:
Yes - tried that, but gives incomplete draw / flicker.

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.

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)


To me it would seem the problems lies in the refresh routine,
you're erasing and then redrawing, a viewed object, this will
cause it to flicker around, even worse if using sizers.
There's probally a better way to do this, but when I've
been faced with this type of problem here's what I would try
and maybe it will help you or give you a different way to
look at it.

I'd create a clone of frame4, maybe frame5, only viewing
one at a time.

In my refresh routine I'd create some type of loop
and alternate them using .hide() .show() and only
do my drawing/erasing on the hidden object.

I think anyway you do it, you should only draw/erase
on a hidden object, you could also have frame4 and 5
be the same, but in the routine that calls refresh, .hide()
4, .show() 5, refresh then redraws 4, and on returning from
refresh, .hide() 5, .show()4. Anyway I thing you get the idea.

Just something I'd try.

Jul 18 '05 #10
Phil Thompson wrote:
There are lots of standard graphics techniques for eliminating flicker
when drawing that you can exploit with PyQt. Double buffering for example
- draw to a QPixmap and then blit it to the QWidget.


ok - I don't know what QPixmap or blit are, but it gives me some clues to
use in google. :)

Thanks for your help

Peter

Jul 18 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

35
by: Vamsi Mudrageda | last post by:
I am kind of new to Python, and after trying and using wxPython, I found it kind of lacking in easy-to-read documentation, speed at loading, and GUI response-time. So I am looking for an another...
2
by: Leif B. Kristensen | last post by:
Can somebody point me to a quick example on how to display the result of an SQL query in a PyQt QListBox? I've googled in vain for this. regards, -- Leif Biberg Kristensen...
4
by: Adrian Casey | last post by:
I'm using a QTimer object to expire certain password protected GUI options in my application after 2 minutes. Currently, the timer is reset each time the user presses the 'OK' button. This is not...
1
by: Chump Wad | last post by:
I will now die. I am too ignorant to make it work. 10.2.setEventCB.py segfaults for me. It is almost there, but it is not there. SoQt.init returns a string, which I can't use as the parent...
3
by: Fabio | last post by:
Hi all, I'm about to write an application, and I'd like to use PyQt, but before choosing this toolkit I would like to clarify some particular licensing issues; if some user has already touched...
1
by: Michael McGarry | last post by:
Hi, I am having a problem making a widget appear. I have 5 widgets which are windows with no parents. 3 of the widgets appear without a problem the other 2 widgets will not appear when I invoke...
0
by: Volker Lenhardt | last post by:
Once again a maybe silly question, but I find no solution, neither in the documentation nor in examples. I have got some different layouts to change place by the help of a QGridLayout in its...
2
by: skawaii | last post by:
Ok, here's what's going on. I've just created a custom widget. it works great. I'm having some trouble, however, figuring out how to allow the said widget to resize. For example, when I throw the...
7
by: Alex Gusarov | last post by:
Hello, I have strong .NET background with C# and want to do some familiar things from it with Python, but don't know how. For example, I created form in qt designer with QCalendarWidget, translated...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.