PDA

View Full Version : How to paint a widget outside paintEvent()



wesley
16th February 2008, 14:08
Hello, can you do me a favor?

Platform: Qtopia 4.3.2

question: paint a widget outside paintEvent() or paint()

problem detail:
I had implemented a custom list view(Inherits QListView), of course , a item delegate to paint each item the list view has.

now, when the text of the focus index has exceeded the text rectangle, I should scroll the text.

my thought is using a timer to scroll text, 2 or 3 characters every time the time-out event happen, but how can i paint the widget now?

the item delegate just can be paint inside paint(), and delegate->paint() just can be called from list view's paintEvent(). that is the real problem. ~_~

may be i can ask Qt to repaint it by using update() or repaint(). But how can i pass a flag or parameter to paintEvent() that I just want to scroll text, not paint a entireness widget.



^_^, Any one have the good solution for this? thank you very much.

jacek
18th February 2008, 00:10
question: paint a widget outside paintEvent() or paint()
answer: you can't. ;)


now, when the text of the focus index has exceeded the text rectangle, I should scroll the text.

my thought is using a timer to scroll text, 2 or 3 characters every time the time-out event happen, but how can i paint the widget now?
It's a good aproach.

See the "Animated Items" example in Qt Model/View In Depth presentation from DevDays 2007 (http://labs.trolltech.com/page/Projects/DevDays/DevDays2007).

wesley
20th February 2008, 10:26
ok, thank you very much

From the documentation, I had found out a way to implement this feature. The way is delegate emit a signal to tell list view to update specified index when a scroll timer event happen.

wesley
20th February 2008, 10:34
and one more question like this kind of problem,

how can i pass a custom parameter to a paint event
I don't want to declare a class-wide parameter. I just need a flag to differentiate some thing.

I had tried to do as follow:

QCoreApplication:: postEvent(this, QEvent::Paint | QEvent::User );

but Qt seems does not allow me to do this, it debug some like that
"QPainter:: ...should no longer be called ...."
"QPaintEngine : return 0 type = 1...",

some things like this, I don't remerber so much.

jacek
20th February 2008, 13:02
how can i pass a custom parameter to a paint event
QPaintEvent doesn't have any flags field or anything you could use to do that. You could try to subclass QPaintEvent and then use dynamic_cast, but that might not be reliable.

wesley
21st February 2008, 06:27
QPaintEvent doesn't have any flags field or anything you could use to do that. You could try to subclass QPaintEvent and then use dynamic_cast, but that might not be reliable.

if i declare a class-wide flag named "bDrawAnimatedCaption",


void on_AnimationTimer_timeout()
{
do some animation work here
... ...

bDrawAnimatedCaption = true;
update(currentIndex()); //it will trigger paintEvent to update current index
}

void paintEvent(QPaintEvent *event)
{
if(bDrawAnimatedCaption)
{
paint animated cation here
... ...
bDrawAnimatedCaption = false;
}
else
{
QListView:: paintEvent(event);
}
}


Are these reliable ?

or is there another solution?
^_^, it just a test, but I hope it can work like this, because i can control the animation more easyer on MyListView side than delegate side.
thank you.

wesley
21st February 2008, 10:30
From Qt Assistant, It is say that QWidget::repaint(QRect &rect) will repaints the widget directly by calling paintEvent() immediately, unless updates are disabled or the widget is hidden.

My list view is Inherits QListView. And I have setUpdatesEnabled to true, of course, My list View is visable on screen.

But why it doesn't call paintEvent() when I call repaint(QRect) in a time event?

update(QModelIndex&) is work. But repaint() seems more reliable when I need a immediate painting.

QWidget is a further base class to QListView, is this a problem?

jacek
21st February 2008, 21:46
Are these reliable ?
Qt tends to merge multiple paint events into one, but this might be not enough. IMO it's better to assume that you don't know when the paint even arrives and avoid changing the state in paintEvent().

Instead of a flag, you could use some variable that denotes the scroll amount. This way you don't have to care how many times and when paintEvent() was called.

wesley
22nd February 2008, 15:19
Qt tends to merge multiple paint events into one, but this might be not enough. IMO it's better to assume that you don't know when the paint even arrives and avoid changing the state in paintEvent().

Instead of a flag, you could use some variable that denotes the scroll amount. This way you don't have to care how many times and when paintEvent() was called.


Firsy of all, thanks for all your help.

But, there is a big problem if we use a flag or a scroll amount in a paintEvent(), we can not differentiate that it is call by we update(currentIndex()) or Qt Server sometimes.


one more question: Qt normally erases the widget's area before the paintEvent() call, now,
How can i disable Qt to erase the content? some times I don't want to clear the content when I call update(), like this task to scroll focus item text.

jacek
25th February 2008, 12:27
But, there is a big problem if we use a flag or a scroll amount in a paintEvent(), we can not differentiate that it is call by we update(currentIndex()) or Qt Server sometimes.
Why do you need to differentiate them? The scroll amount depends on time --- who and when caused the repaint doesn't matter.


How can i disable Qt to erase the content?
You can set the Qt::WA_OpaquePaintEvent widget attribute.

wesley
27th February 2008, 03:19
this thread is end. thanks for every one.