PDA

View Full Version : An example puzzle me, please help



HelloDan
7th March 2009, 08:29
//ticker.h
#ifndef TICKER_H
#define TICKER_H

#include <QWidget>

class Ticker : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText)

public:
Ticker(QWidget *parent = 0);

void setText(const QString &newText);
QString text() const { return myText; }
QSize sizeHint() const;

protected:
void paintEvent(QPaintEvent *event);
void timerEvent(QTimerEvent *event);
void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event);

private:
QString myText;
int offset;
int myTimerId;
};

#endif


//ticker.cpp
#include <QtGui>

#include "ticker.h"

Ticker::Ticker(QWidget *parent)
: QWidget(parent)
{
offset = 0;
myTimerId = 0;
}

void Ticker::setText(const QString &newText)
{
myText = newText;
update();
updateGeometry();
}

QSize Ticker::sizeHint() const
{
return fontMetrics().size(0, text());
}

void Ticker::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this);

int textWidth = fontMetrics().width(text());
if (textWidth < 1)
return;
int x = -offset;
while (x < width()) {
painter.drawText(x, 0, textWidth, height(),
Qt::AlignLeft | Qt::AlignVCenter, text());
x += textWidth;
}
}

void Ticker::showEvent(QShowEvent * /* event */)
{
myTimerId = startTimer(30);
}

void Ticker::timerEvent(QTimerEvent *event)
{
if (event->timerId() == myTimerId) {
++offset;
if (offset >= fontMetrics().width(text()))
offset = 0;
scroll(-1, 0);
} else {
QWidget::timerEvent(event);
}
}

void Ticker::hideEvent(QHideEvent * /* event */)
{
killTimer(myTimerId);
myTimerId = 0;
}

//main.cpp
#include <QApplication>

#include "ticker.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Ticker ticker;
ticker.setWindowTitle(QObject::tr("Ticker"));
ticker.setText(QObject::tr("How long it lasted was impossible to "
"say ++ "));
ticker.show();
return app.exec();
}



This is an example from C++ GUI programming with Qt4 , second edition.

This example puzzle me.

1 , Q_PROPERTY(QString text READ text WRITE setText). Q_PROPERTY macro is used for declaring properties in classes that inherit QObject. Properties behave like class data members, but they have additional features accessible through the Meta-Object System. But I do think I can do the same thing with QString and the function I write the same with the Q_PROPERTY declare. What's the function of this Q_PROPERTY?

2 , Check all over the code, I can not find any place has called showEvent(), for me, it should not start the timer. But in fact, it does start it and work well. Why?

3 int x = -offset;
while (x < width()) {
painter.drawText(x, 0, textWidth, height(),
Qt::AlignLeft | Qt::AlignVCenter, text());
//.......

The first time of drawText will draw a part of the text outside the widget, and only the fragment inside the widget will show, right?

4 scroll(-1,0); //Scrolls the widget including its children dx pixels to the right and dy downward. Both dx and dy may be negative. After scrolling, the widgets will receive paint events for the areas that need to be repainted. That is to say, the widget can be very long, outside the viewport and only will draw text in the viewport?


Still know little, Thanks for your help!

wysota
7th March 2009, 08:56
1 , Q_PROPERTY(QString text READ text WRITE setText). Q_PROPERTY macro is used for declaring properties in classes that inherit QObject. Properties behave like class data members, but they have additional features accessible through the Meta-Object System. But I do think I can do the same thing with QString and the function I write the same with the Q_PROPERTY declare. What's the function of this Q_PROPERTY?
As you quoted it gives you additional features. Like the ability to set the property value from Designer or from a script. In addition to that you don't have to know that a certain property/method exists to be able to use it - you can query the meta-object of the class for a list of methods (signals, slots, properties) and use a pair of generic QObject::property() and QObject::setProperty() methods to change their values. This is especially useful when providing objects through a plugin. There are also additional benefits when using QWizard or QDataWidgetMapper.


2 , Check all over the code, I can not find any place has called showEvent(), for me, it should not start the timer. But in fact, it does start it and work well. Why?
showEvent() is an event handler called automatically by Qt when the widget is shown (i.e. by calling QWidget::show()).


The first time of drawText will draw a part of the text outside the widget, and only the fragment inside the widget will show, right?
Yes, that's correct.


4 scroll(-1,0); //Scrolls the widget including its children dx pixels to the right and dy downward. Both dx and dy may be negative. After scrolling, the widgets will receive paint events for the areas that need to be repainted. That is to say, the widget can be very long, outside the viewport and only will draw text in the viewport?
The widget is always clipped to its parent. So if the widget is larger than the parent, only the part contained in the parent's rectangle will be visible.

HelloDan
7th March 2009, 12:33
Thanks wysota

But I try without Q_PROPERTY(QString text READ text WRITE setText).

It can do the same things. I have not yet finished the C++ GUI programming with Qt4, but just chapter 12. Can you give me an example or a link to see the inside feature of Q_PROPERTY?

Thanks!

wysota
7th March 2009, 15:31
Thanks wysota

But I try without Q_PROPERTY(QString text READ text WRITE setText).

It can do the same things.

You can use setProperty() on the property and it changes the text used by the widget? If so then it means you didn't rebuild the application properly.

HelloDan
7th March 2009, 16:44
You can use setProperty() on the property and it changes the text used by the widget? If so then it means you didn't rebuild the application properly.

I have no idea.

I delete the Q_PROPERTY line. and rebuild in this way.

make clean
make


It can do the same thing.

Maybe now I have not the foundation to comprehend the Q_PROPERTY.


bool QObject::setProperty ( const char * name, const QVariant & value )
Sets the value of the object's name property to value.
If the property is defined in the class using Q_PROPERTY then true is returned on success and false otherwise. If the property is not defined using Q_PROPERTY, and therefore not listed in the meta-object, it is added as a dynamic property and false is returned.
Information about all available properties is provided through the metaObject() and dynamicPropertyNames().

What for ? It puzzles me further more. Can you give me an example? Or I can refer to what material? Thanks!

wysota
7th March 2009, 17:47
It can do the same thing.
Because you are not using anything Q_PROPERTY offers. If I have a car and I don't use the wipes, I can take them off and say the car still behaves as it did before. Q_PROPERTY is an extra functionality that you are simply not using at the time.

Please read about Q_PROPERTY and meta-object system in Qt Assistant. It's a wide topic, impossible to cover in a forum thread.

HelloDan
8th March 2009, 08:47
Thank you! Maybe I should put it aside now. But I will learn further more and master it.

Thanks again!