2005年02月26日

source:forever.h forever.cpp(from qt/examples)
the Makefile:

CC= g++
INCL= -I$(QTDIR)/include
CFLAGS= -Wall -O
LFLAGS= -L$(QTDIR)/lib -L/usr/X11R6/lib
LIBS= -lqt -lX11

all: forever

forever: forever.o forever.moc.o
$(CC) $(LFLAGS) -o $@ $^ $(LIBS)

forever.o: forever.cpp forever.h

forever.moc.cpp: forever.h
$(QTDIR)/bin/moc forever.h -o $@

clean:
rm -f forever
rm -f *.o
rm -f .moc.cpp

.SUFFIXES: .cpp

.cpp.o:
$(CC) $(CFLAGS) $(INCL) -c $< -o $@

Let’s take a look at the contents of the user-provided input files that are relevant to this minimal project. Here is the `Makefile.am’:

bin_PROGRAMS = foonly
foonly_SOURCES = main.c foo.c foo.h nly.c scanner.l parser.y
foonly_LDADD = @LEXLIB@

This `Makefile.am’ specifies that we want a program called `foonly’ to be built and installed in the `bin’ directory when make install is run. The source files that are used to build `foonly’ are the C source files `main.c’, `foo.c’, `nly.c’ and `foo.h’, the lex program in `scanner.l’ and a yacc grammar in `parser.y’. This points out a particularly nice aspect about Automake: because lex and yacc both generate intermediate C programs from their input files, Automake knows how to build such intermediate files and link them into the final executable. Finally, we must remember to link a suitable lex library, if `configure’ concludes that one is needed.

And here is the `configure.in’:

dnl Process this file with autoconf to produce a configure script.
AC_INIT(main.c)
AM_INIT_AUTOMAKE(foonly, 1.0)
AC_PROG_CC
AM_PROG_LEX
AC_PROG_YACC
AC_OUTPUT(Makefile)

This `configure.in’ invokes some mandatory Autoconf and Automake initialization macros, and then calls on some Autoconf macros from the AC_PROG family to find suitable C compiler, lex, and yacc programs. Finally, the AC_OUTPUT macro is used to cause the generated `configure’ script to output a `Makefile’—but from what? It is processed from `Makefile.in’, which Automake produces for you based on your `Makefile.am’ (see section C. Generated File Dependencies).

2005年01月29日

关于布局
QVBoxLayout
QHBoxLayout
QGridLayout
Inherits QBoxLayout.
常用的函数:
QLayout ( QWidget * parent, int margin = 0, int spacing = -1, const char * name = 0 )
QLayout ( QLayout * parentLayout, int spacing = -1, const char * name = 0 )
void addChildLayout ( QLayout * l )
The margin is the number of pixels between the edge of the widget and its managed children. The spacing is the default number of pixels between neighboring children. If spacing is -1 the value of margin is used for spacing.

void QLayout::setMenuBar ( QMenuBar * w ) [virtual]
Makes the geometry manager take account of the menu bar w. All child widgets are placed below the bottom edge of the menu bar.
bool QLayout::activate ()
Redoes the layout for mainWidget(). You should generally not need to call this because it is automatically called at the most appropriate times.
However, if you set up a QLayout for a visible widget without resizing that widget, you will need to call this function in order to lay it out.

QBoxLayout ( QWidget * parent, Direction d, int margin = 0, int spacing = -1, const char * name = 0 )
QBoxLayout ( QLayout * parentLayout, Direction d, int spacing = -1, const char * name = 0 )
Inherits QLayout.
Inherited by QHBoxLayout and QVBoxLayout.
void addWidget ( QWidget * widget, int stretch = 0, int alignment = 0 )
void addLayout ( QLayout * layout, int stretch = 0 )

bool setStretchFactor ( QWidget * w, int stretch )
bool setStretchFactor ( QLayout * l, int stretch )

QHBoxLayout ( QWidget * parent, int margin = 0, int spacing = -1, const char * name = 0 )
QHBoxLayout ( QLayout * parentLayout, int spacing = -1, const char * name = 0 )

关于QLabel
setScaledContents( TRUE );//可以使Label内的图像随label大小而拉伸,一直填满label
setPaletteBackgroundPixmap( pix );//拉伸时自动填充label
setPixmap(pix);//拉伸时大小不变

main函数中若
mainWin = new MyWidget;
app.setMainWidget(mainWin);
return app.exec;
程序关闭时不会调MyWidget;的析构函数
除非在app.exec后加上
delete mainWin;
或者
MyWidget mainWin;
app.setMainWidget(&mainWin);
return app.exec;

2005年01月23日

示例代码
详细请见http://www.digitalfanatics.org/projects/qt_tutorial/chapter02.html
#ifndef PROPOBJECT_H
#define PROPOBJECT_H

#include
#include

class PropObject : public QObject
{
Q_OBJECT

Q_PROPERTY( TestProperty testProperty READ testProperty WRITE setTestProperty )
Q_ENUMS( TestProperty )

Q_PROPERTY( QString anotherProperty READ anotherProperty )

public:
PropObject( QObject *parent=0, char *name=0 );

enum TestProperty { InitialValue, AnotherValue };

void setTestProperty( TestProperty p );
TestProperty testProperty() const;

QString anotherProperty() const { return QString( “I’m read-only!” ); }

private:
TestProperty m_testProperty;
};

#endif

请注意Q_PROPERTY的参数之间没有逗号,语法为属性的类型,后面接名字,然后是READ或者WRITE,最后接相应的函数名字
读和写属性的函数的要求(偷懒不翻译了:):
There is nothing special about the read and write member functions. The only restriction is that the reader must be of the parameters type and take no arguments (i.e. it has to be of the type void) while the writer must accept only one argument and it has to be of the parameter type.
It is common practice to declare write functions as slots. This increases the easy of re-use since most write functions are natural slots. Some of these are also candidates for emitting signals.
例如:propobject.cpp.
#include “propobject.h”

PropObject::PropObject( QObject *parent, char *name ) : QObject( parent, name )
{
m_testProperty = InitialValue;
}

void PropObject::setTestProperty( TestProperty p ) { m_testProperty = p; }
PropObject::TestProperty PropObject::testProperty() const { return m_testProperty; }

#include
#include

#include “propobject.h”

int main( int argc, char **argv )
{
QApplication a( argc, argv );

QObject *o = new PropObject();

std::cout << o->property( “testProperty” ).toString() << std::endl;

o->setProperty( “testProperty”, “AnotherValue” );
std::cout << o->property( “testProperty” ).toString() << std::endl;

std::cout << o->property( “anotherProperty” ).toString() << std::endl;

return 0;
}

输出:
$ ./prop
0
1
I’m read-only!
$

2005年01月19日

关于QFile,QStringList,QTextStream
判断一个文件是否存在,若不存在则创建
QFile filename;
if(!QFile::exits(myfile))
{
filename = QFile(myfile);//在当前文件夹下创建了文件myfile
}
怎样写文件
QStringList lines;
lines.append(“Hello world!”);
lines.append(“It’s good beginning,isn’t it?”);
lines.append(“I’am Yolanda.”);
lines.append(“If you are insterested in these articles, please write down something :) ”);
if ( file.open( IO_WriteOnly ) ) {
QTextStream stream( &file );
for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
stream << *it << “\n”;
file.close();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QString QStringList:: join ( const QString & sep ) const ,可以把一串QString 组合成QStirng
可以向下面这样操作
QStringList fonts;
fonts.append( “Times” );
fonts += “Courier”;
fonts += “Courier New”;
fonts << “Helvetica [Cronyx]” << “Helvetica [Adobe]“;

for ( QStringList::Iterator it = fonts.begin(); it != fonts.end(); ++it ) {
cout << *it << “:”;
}
cout << endl;

QString str=fonts.join(“:”); //和上面的结果相同
cout<

但我不知道有没有可以直接创建xml文件的方法,DomDocument虽然可以创建,但不知道怎么才能把它写回文件
原来用DomDocumnet::toString();就可以了:)
想下面这样:
QDomDocument doc( “MyML” );
QDomElement root = doc.createElement( “MyML” );
doc.appendChild( root );

QDomElement tag = doc.createElement( “Greeting” );
root.appendChild( tag );

QDomText t = doc.createTextNode( “Hello World” );
tag.appendChild( t );

QString xml = doc.toString();

2005年01月12日

KDE
#include
QString locate(“data”,QString(“amarok/images”));

可以返回amarok安装目录的绝对路径/opt/kde3/share/apps/amarok/images

Qt
QPalette
QColorGroup
真是奇怪阿,Disabled状态竟然调的是QColorGroup::Text,让我猜了好久。

Qt
setPaletteBackgroundPixmap();
可以使窗体擦除时无闪动
重载QPushButton::drawButton(QPainter *p);
QPushButton::paintEvent(QPainEvent *event);
可以加速画button的速度
例如:
void CSkinButton::paintEvent(QPaintEvent * e) //It is this function that make the repaint very quick,why??? I don’t know very well.
{
if(toggleType() == QButton::Toggle)
{
//QSharedDoubleBuffer buffer( this );
drawButton( & QPainter(this) ); //This is very important , maybe it make the area small
}
}

void CSkinButton::drawButton(QPainter * painter) {
if(isEnabled())
{
if(toggleType() == QButton::SingleShot)
{
painter->drawPixmap(0,0,*m_item->m_normalImage);
}
else if(toggleType() == QButton::Toggle)
{
if(state() == QButton::On)
{
//setPaletteBackgroundPixmap(*m_item->m_activeImage);
painter->drawPixmap(0,0,*m_item->m_activeImage);
}
else
{
//setPaletteBackgroundPixmap(*m_item->m_normalImage);
painter->drawPixmap(0,0,*m_item->m_normalImage);
}
}
}
else
{
painter->drawPixmap(0,0,*m_item->m_disabledImage);
}
}

用小图来填充大图
QPixmap mLabPix2(“/root/mywork/qtapps/test/images/label2.png”);
QPixmap mLabBigPix(1000,mFancyLab->height());

int i;
int widthBig = 1000;//width()-mFancyLab->width();
int widthSml = mLabPix2.width();
for(i = 0 ; i < widthBig; i+=widthSml)
{
copyBlt(&mLabBigPix, i, 0, &mLabPix2, 0, 0,widthSml, mFancyLab->height() );
}
if(mLabPix2.isNull())
{
qWarning(“Can’t find the pixmap for fancy label”);
}
else
{
mExtLab->setPixmap(mLabBigPix);
}

QMainWindow::addDockWindow ( QDockWindow * dockWindow, Dock edge = DockTop, bool newLine = FALSE ) ;
添加布局,组件在QMainWiddow

2005年01月08日

001
KDE调试信息输出
#include
kdDebug() << k_funcinfo << endl;
输出所在的函数的名字,参数,返回值

Qt 画图后擦除,主窗口拖动的实现
主要应用于拖动无边框窗口时,画出窗口轮廓
void CSkinWidget::mousePressEvent( QMouseEvent *e )
{
if(error)
{
QWidget::mousePressEvent( e );
}
else
{
if(e->button()==Qt::LeftButton)
{
clickPos = e->pos();
drag_enable=1;
}
}
}
void CSkinWidget::mouseMoveEvent( QMouseEvent *e )
{
if(error)
{
QWidget::mouseMoveEvent (e);
}
else
{
if(drag_enable)
{
QPainter *dr = new QPainter (QApplication::desktop()->screen(0),TRUE);
dr->setRasterOp(Qt::XorROP);
QColor color(255,255,255);
QPen pen(color);
dr->setPen(pen);
if(!rect.isNull())
dr->drawRect(rect);
rect = QRect(e->globalX()-clickPos.x(),e->globalY()-clickPos.y(),back.size().width(),back.size().height());
dr->drawRect(rect);
}
}
}

void CSkinWidget::mouseReleaseEvent (QMouseEvent *e)
{
if(error)
{
QWidget::mouseReleaseEvent (e);
}
else
{
if(drag_enable)
{
dr->drawRect(rect);
move( e->globalPos() – clickPos );
rect=QRect();
drag_enable=0;
}
}
repaint();
}

Qt 调试信息的输出
qWarning(“something to output”);
QString str;
qWarning(” %s”, str.latin1());

QDomDocument 读配置文件
下面是一个xml文件,记录了amarok各个组件的位置信息

default





下面这些代码,从上面的文件读出信息并输出:
QDomDocument docSkin(“amarok_skin”);
QFile skinfile(“skin.xml”);
if(!skinfile.open(IO_ReadOnly))
{
qWarning(“cann’t open file”);
}
if(!mydoc.setContent(&myfile))
{
qWarning(“cann’t setcontent file”);
myfile.close();
}

QDomElement docElem = mydoc.documentElement();
cout<<"begin to read elements"< for ( QDomNode n = docElem.firstChild(); !n.isNull(); n = n.nextSibling() )
{

QDomElement element = n.toElement();
QString elename = element.tagName();
char * dd = "sdfff";
//qWarning("elename is %s ", elename.latin1 ());

if(elename.contains("skinname") > 0)
{
QString skinname = element.text();
qWarning(“skin name is %s”, skinname.latin1());
}
else if(elename.contains(“position”) > 0)
{
for ( QDomNode nAttr = n.firstChild(); !nAttr.isNull(); nAttr = nAttr.nextSibling() )
{
QDomElement widget_nm = nAttr.toElement();
QString widget_nmStr = widget_nm.tagName();
QRect mRect;
mRect.setRect(widget_nm.attributeNode(“x”).value().toInt(),widget_nm.attributeNode(“y”).value().toInt(),widget_nm.attributeNode(“width”).value().toInt(),widget_nm.attributeNode(“height”).value().toInt());

qWarning(“The position of widget %s is ( %d, %d, %d, %d)”, widget_nmStr.latin1(), mRect.x(), mRect.y(), mRect.width(), mRect.height());
}
}
}

QPushButton Tips
可以设置setIconSet(const QIconSet &);
来设置在不同状态的icon,例如
QIconSet iconSet;
iconSet.setPixmap( pixmap, QIconSet::Automatic, QIconSet::Normal, QIconSet::Off );
iconSet.setPixmap( pixmap, QIconSet::Automatic, QIconSet::Normal, QIconSet::On );
iconSet.setPixmap( pixmap, QIconSet::Automatic, QIconSet::Disabled, QIconSet::Off );
setIconSet( iconSet );