Labels

25/03/2011

Linux library link configuration (libquazip.so)

In Linux system, understanding of how system or application library works is very important. Many applications you download are source files which need to be compiled. for example: qmake, make, make install.
After "make" the source file (typically lib), the lib files will be created, such as:

ln -s libquazip.so.1.0.0 libquazip.so
ln -s libquazip.so.1.0.0 libquazip.so.1
ln -s libquazip.so.1.0.0 libquazip.so.1.0

but these lib file are not installed in Linux system.
After "make install", all lib files has been installed in Linux system.

ln -f -s "libquazip.so.1.0.0" "/usr/local/lib/libquazip.so"
ln -f -s "libquazip.so.1.0.0" "/usr/local/lib/libquazip.so.1"
ln -f -s "libquazip.so.1.0.0" "/usr/local/lib/libquazip.so.1.0"


However, even you "make install" lib files, you may still get error message when you run Qt application. for example, I "make install" QuaZIP package, and successfully compile a test.pro which come with this package, but i still got error message when i run the program:

Starting /home/czhang/quazip-0.3/test/zip-build-desktop/zip...
/home/czhang/quazip-0.3/test/zip-build-desktop/zip: error while loading shared libraries: libquazip.so.1: cannot open shared object file: No such file or directory
/home/czhang/quazip-0.3/test/zip-build-desktop/zip exited with code 127


Why?!! I have been struggling on this problem for long time.

Here is what i understand and solve the problem.

First of all, take a look at "ldconfig" - configure dynamic linker run-time bindings
$ man ldconfig
All applications, if they need lib to run, will check from here first /etc/ld.so.conf
take a look ld.so.conf:
$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf


It re-direct to /etc/ld.so.conf.d  and all .conf file will be checked through.
Let's take a look at ld.so.conf.d folder
$ ls /etc/ld.so.conf.d

GL.conf            libasound2.conf   x86_64-linux-gnu.conf
lib32asound2.conf  libc.conf        Qtlib.conf


in here, we can see a Qtlib.conf file. If you take a look at it, you will see all Qt lib is setting in
/home/czhang/qtsdk-2010.04/lib

When I "make install" QuaZip package, I got message like:

ln -f -s "libquazip.so.1.0.0" "/usr/local/lib/libquazip.so"
ln -f -s "libquazip.so.1.0.0" "/usr/local/lib/libquazip.so.1"
ln -f -s "libquazip.so.1.0.0" "/usr/local/lib/libquazip.so.1.0"


This means all QuaZip libs are stored in /usr/local/lib/

So, I create a new .conf file which call qauzip.conf
$ gedit qauzip.conf
add "/usr/local/lib" in it.

From now on, when Qt tries to use QuaZip lib, it can be found.

Re-compile my "test.pro", and run it, works! :)

Happy end.

EDIT:
or, just simply
$ sudo cp -a /home/czhang/quazip-0.3/quazip libquazip* /usr/lib64
=================================================
EDIT:

when i compile my own program which including QuaZip, i got error messages:

error: undefined reference to `QuaZip::QuaZip(QString const&)'
error: undefined reference to `QuaZip::open(QuaZip::Mode, zlib_filefunc_def_s*)'
...

Then I took a look .pro file,

INCLUDEPATH += /home/czhang/quazip-0.3/quazip
LIBS += -L -lquazip

Actually, I don't really understand the -L. After doing some studies, i learned:

INCLUDEPATH:
This variable specifies the #include (normally header file) directories which should be searched when compiling the project.

LIBS:
This variable contains a list of libraries to be linked into the project. You can use the Unix -l (library) and -L (library path) flags and qmake will do the correct thing with these libraries on Windows (namely this means passing the full path of the library to the linker). The only limitation to this is the library must exist, for qmake to find which directory a -l lib lives in.

Therefore, my .pro file should be like:


INCLUDEPATH += /home/czhang/quazip-0.3/quazip
LIBS += -L/home/czhang/quazip-0.3/quazip -lquazip
Or:
INCLUDEPATH += /home/czhang/quazip-0.3/quazip
LIBS += -lquazip


$ rsync -av czhang@10.0.1.202://build/czhang/qt-everywhere-op
ensource-src-4.7.0/projects/quazip-0.3/quazip/libquazip.so* /usr/lib

11/03/2011

The moment the earth quack hit Christchurch

Thought this might be of interest. This is caused by an upward force at the moment of 2 g’s gravity.

The moment the quack hit Christchurch - as captured by a tourist

08/03/2011

some Qt hints

1)
Pushbotton toggled slot:

To make the pushbotton toggled slot working, two parameters need to setup:

btn2->setCheckable(TRUE);
btn2->setChecked(TRUE);
 
2)
ListView application:

In QListView, i need to display all files in a directory, and pass the file name when i click a file from list.
 
QDirModel *dirModel = new QDirModel;
ui->listView->setModel(dirModel);
ui->listView->setRootIndex(dirModel->index(QString(QApplication::applicationDirPath()).append("/db")));

connect(ui->listView,SIGNAL(clicked(const QModelIndex &)),this,SLOT(selectionChanged(const QModelIndex &)));
 
QString hiscDialog::selectionChanged(const QModelIndex & index)
{
ui->label_db->setText(index.data().toString());
dbFile = QString(QApplication::applicationDirPath()).append("/db/" + index.data().toString());
return dbFile;
}

3)
QSqlTableModel:
 
After i define a model, and try to read out record from the database, I can only get 256 records each time. 
It looks like the Qt has some buffer to protect the database.  
To get all records from database, i can 

while (cDmodel->canFetchMore())
cDmodel->fetchMore();

4)
Read array from .ini file:

To define syntax in .ini file, the first field in each entry is the index, the second the name of the value, and the value itself comes after an equal sign. also need the size attribute.

This defines a 6-element array called StageNum, where each element has a value called "cycle1" (test.ini):
[StageNum]
size = 6
0/cycle1 = 7
1/cy
cle1 = 2
2/cycle1 = 5
3/cycle1 = 2
4/cycle1 = 3
5/cycle1 = 0
To read array from .ini file:

QSettings m4Settings("test.ini", QSettings::IniFormat);
int arySize = m4Settings.beginReadArray("StageNum");
for (int vL = 0; vL < arySize; vL ++)
{
m4Settings.setArrayIndex(vL);
 
cycleStageNum[vL] = m4Settings.value("cycle1","0").toInt();

 }
m4Settings.endArray();


both read and write:
#include 
#include
#include

int data[] = { 3, 1, 4, 1, 5, 9 };

int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);

QSettings m4Settings("test.ini", QSettings::IniFormat);

// Write a test file
m4Settings.beginWriteArray("StageNum");
for (unsigned int i = 0; i < sizeof(data)/sizeof(int); ++i) {
m4Settings.setArrayIndex(i);
m4Settings.setValue("cy1", data[i]);
}
m4Settings.endArray();

// read it back
int arySize = m4Settings.beginReadArray("StageNum");
qDebug() << "arySize =" << arySize;
for (int vL = 0; vL < arySize; vL ++)
{
m4Settings.setArrayIndex(vL);
qDebug()
<< "index =" << vL
<< "cy1 =" << m4Settings.value("cy1", "0").toInt();
}
m4Settings.endArray();

return app.exec();
}

5) 
Increment label id in loop For()

in my program, i have 10 labels, which indicate 10 led lights.
I can change the color for each label by using

ui->label_led_1->setPixmap(picLedRed);
ui->label_led_2->setPixmap(picLedRed);
...

To simplify this code by using a loop:

for (int i = 1; i <= 10; i++)
{
QLabel *label = qFindChild(this, "label_led_" + QString::number(i));
if (label) 
      label->setPixmap(picLedRed); 
}