- 9:30 Guest registration
- 10:00 Key-note: Qt Strategy & Roadmap
- 10:30 Product presentation: Qt 4.6 Technical highlights
- 11:30 Embedded case-study
- 12:00 Lunch & demos
- 13:00 Embedded case-study
- 13:30 Tech session: An Introduction to Qt development for Symbian
- 14:15 Tea-break & demo
- 14:30 Tech session: Introducing the Qt Kinetic Project and QML
- 15:15 Tech session: Using Multi-touch and gesture with Qt
- 16:00 Lucky-draw and Closing remarks
2009-11-27
Qt Conference -Taiwan 2009
[Android] Create compound controls in Qt and Android
If you are a programmer who is familiar with Qt and is writing Android application at the same time, just like me. You might discover that creating a compound control widget in Android and Qt is a bit different. For example, I would like a compound control widget that shows current time and am/pm label if the user prefers not to use 24-hour format.
In Qt, you might extend a QWidget and attach a derived QLayout to it.
class CompondTimeWidget : public QWidget {
public:
CompondTimeWidget(QWidget* parent) : QWidget(parent) {
QHBoxLayout* mainLayout = new QHBoxLayout(this);
// ...
}
// ...
};
The QWidget and QLayout are in the difference class hierarchy and every QWidget needs a layout engine attached to it to layout child widgets defined inside it.
But, in Android, things are a bit different. The View and LinearLayout, for instance, are in the same class inheritance hierarchy. For this task, it's better to be done like this,
public class CompoundTimeWidget extends LinearLayout {
public CompoundTimeWidget(Context context, AttributeSet attrs) {
super(context, attrs);
//
TextView label = new TextView(context);
addView(label, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// Get the rest of the design from xml file.
View amPmView = mLayoutInflater.inflate(R.layout.am_pm_widget, this, false);
addView(amPmView);
// ...
}
// ...
}
I am not very biased towards Qt. Still, it's not natural to say, a widget is a LinearLayout. Which one is better? You tell me.
2009-04-30
Use QSettings
Normally, different applications have different ways to handle user preferences. For instance, it may be natural to choose Tcl script to save preferences for those applications that support Tcl scripting. But some specific settings, like window geometries opened last time, we don't want to trouble users to modify manually. We can choose whatever we feel convenient and they don't care about these settings.
In this case, the best way to handle this is using QSettings. In Unix platforms, QSettings put setting files under ~/.config according to application name and the organization that produces it. You may see directory structure like this,
[yenliangl@halo]:~/.config > ll total 13 drwx------ 2 yenliangl staff 512 May 16 2007 autostart/ drwxr-x--- 2 yenliangl staff 512 Apr 7 19:30 fixit/ drwx------ 2 yenliangl staff 512 Apr 30 12:28 gtk-2.0/ drwxr-x--- 2 yenliangl staff 512 Jul 17 2008 menus/ drwxr-x--- 2 yenliangl staff 512 Dec 24 16:43 Synopsys/ drwxr-xr-x 2 yenliangl staff 512 Jul 10 2007 Trolltech/ -rw------- 1 yenliangl staff 5769 Apr 22 13:47 Trolltech.conf -rw-r----- 1 yenliangl staff 242 Apr 13 18:38 Unknown Organization.confAll Qt-related settings are located at Trolltech/ or in Trolltech.conf. How do we use QSettings? First, we let QSettings know our organization and product by,
QCoreApplication::setOrganizationName( "SomeCompany" ); QCoreApplication::setOrganizationDomain( "somecompany.com" ); QCoreApplication::setApplicationName( "MyTool" );and then, we have two private methods defined in our MainWindow class to write/read settings,
class MainWindow : public QMainWindow {
Q_OBJECT
public:
void closeEvent(QCloseEvent* e);
// ...
private:
void read_settings();
void write_settings();
// ...
};
In MainWindow::MainWindow(), we add a call to read_settings(),
MainWindow::MainWindow( /* ... */ )
{
// ...
read_settings();
}
and add a call to write_settings() as we exit application,
void MainWindow::closeEvent(QCloseEvent* e)
{
// ...
write_settings();
}
The definitions of read_settings() and write_settings() should look like,
void MainWindow::read_settings()
{
QSettings settings;
settings.beginGroup( "MainWindow" );
restoreState( settings.value( "wm_state" ).toByteArray() ); // 可能有問題喔,如下。
resize( settings.value( "size", QSize( 400, 400 ) ).toSize() );
move( settings.value( "pos" ).toPoint() );
settings.endGroup();
}
void MainWindow::write_settings()
{
QSettings settings;
settings.beginGroup( "MainWindow" );
settings.setValue( "wm_state", saveState() ); // 可能有問題喔,如下。
settings.setValue( "size", size() );
settings.setValue( "pos", pos() );
settings.endGroup();
}
set? not yet. If you are using QDockWidget or QToolBar in your application, we should see an error message at application run-time, saying that QDockWidget doesn't have objectName property set. From release note of Qt4, you should find,
The QMainWindow::saveState() and QMainWindow::restoreState() functions no longer fallback to using the windowTitle property when the objectName property is not set on a QToolBar or QDockWidget; this behavior was undocumented and has been removed.It points out that you need to set objectName property manually. Simple!
myDock->setObjectName("whatever name"); // Or/And
myToolBar->setObjectName("whatever name");
Now. We're done. Run your application. You will discover your application remembers the window state and even the states of dock widgets.
2009-04-29
Qt4的安裝與編譯
[josh@halo:~/qt-x11-opensource-src-4.5.0 > ./configure --help
,來看看編譯時可以用的選項。我個人大約會注意的有這幾個,
- -prefix:在你想將Qt安裝在特定的目錄時,可以用這個選項。通常,在一般的開發環境中,所有的開發工具會安裝在同一父目錄下,再由Make rules指定每一個Release應該使用的工具或函式庫版本。這樣的安排,主要是要避免不同開發者之間鍊結錯誤函式庫的機會。這時候,管理者就可以使用這個選項將Qt安裝在規定的目錄下。
- -release|-debug|-debug-and-release:是否產生偵錯版本。
- -shared|-static:這個選項很有意思。之前提過在LGPL下,Qt的函式庫必須被動態鍊結,也就是你的程式必須動態開啟Qt的.so函式庫。而-shared這個選項,就是編譯出一套Qt的.so函式庫。相反地,當你希望Qt的函式庫是整個包含在你的執行檔時,就可以用-static來編譯出Qt的Archived函式庫(.a),之後再連結進執行檔。這個情形下,使用ldd,就不會列出Qt的任何.so檔。
- -make或-nomake:通常,你可以經由這個選項指定要編譯的模組。我通常覺得不需要編譯examples和demos兩項,所以我可以把他們加在-nomake裡。
[josh@halo:/tmp/qt-x11-opensource-src-4.5.0 > ./configure -prefix /home/josh/qt/4.5.0 -shared -debug-and-release -nomake "examples demos translation"
[josh@halo:/tmp/qt-x11-opensource-src-4.5.0 > gmake; gmake install
以我的機器,大概15-30分鐘,編譯就完成了。接著,將Qt的環境加入系統中(以bash為例),
export QTDIR=/home/josh/qt/4.5.0
export PATH= "$QTDIR/bin:$PATH"
export LD_LIBRARY_PATH= $QTDIR/lib:$LD_LIBRARY_PATH
現在,就可以試著執行Qt內付的工具,如assistant或是qtconfig等。
2007-07-29
Qt Programming - Callback function與signal/Slot
在許多的傳統的UI設計中,經常會有所謂Callback function的設計,例如這個按鈕按下去(event)之後
需要做什麼事,是你事先並無法確定或是缺乏一些資訊來進行時,我們就必須利用Callback function先將
function pointer註冊在這個按鈕中,等到他被按下後,便執行此function。所以這個function會被稱
之為Callback function,因為是註冊後才會被呼叫。
但是,有X11/Xt 經驗的設計師就會明白Callback function的缺點有下:
- 缺乏function signature的檢查:Callback function是以function pointer的方式註冊,所以compiler是無法在compile的時候幫你做檢查,通常是程式在執行時才會發生錯誤。
Qt的Signal/Slot設計:
Qt的Signal/Slot機制使得programmer可以更快找出這類問題,並縮短程式開發的時間(大部分的
Programmer認為找出Bug在哪裡的時間遠大於修正他的時間)。
Qt利用moc這個類似preprocessor的程式將程式碼中的signal和slot編成可以編譯的meta object檔。
使programmer在寫程式時減少參數傳錯的機會。例如,
connect( this, SIGNAL( myButtonClicked( int, char) ),上面的例子中,myButtonClicked和doSomething的function signature必須完全吻合。而他們的宣
this, SLOT( doSomething( int, char ) ) );
告應該如下:
class MyClass : public QObject {甚至,使用者可以在一些特定的情況下,自己發出signal,如
Q_OBJECT
public:
/* ... */
signals:
void myButtonClicked(int, char);
public slots:
void doSomething(int, char);
private:
/* ... */
};
// 如果按鈕被按時,而在接收端,就會執行
emit myButtonClicked(3, 'c'); //
void是不是很簡單呢?
MyClass::doSomething( int k, char c)
{
// k = 3, c = 'c';
}
2007-07-28
Qt Programming - 發展環境
雖然,KDE這個Team做了Kdevelop這個東西,但是鮮為人知的是他們也另外為了Emacs做了一個叫做kde-emacs的package。從他的名字可以知道,他是專門替在Emacs下寫Qt/KDE程式的工程師設計的。感動吧!
這套emacs的擴充套件可以從kde-sdk中取得。
此外,為了讓在Emacs下寫程式的工程師效率更高,另外也有一個好東西要介紹一下,那就是ECB了。顧名思義,就是Emacs Code Browser。若是將這兩套東西搭配起來用,其實我個人認為是遠超過商用IDE介面的。而且是跨平台。只要有Emacs的地方就可以用。

上圖就是整合起來的畫面。Cool? 用用看吧,你會喜歡他的。
Qt Programming - 序言
- 基本的UI Callback 的觀念
- 何謂Observer。
- Qt的Signal/Slot設計方式。
- 使用QProcess應該注意的地方。
- 如何使用Qt的Layout來安排UI的Widgets.
- 利用QThread發展Multithreaded的程式。
- 何謂Command pattern。
- 如何使用QMutex,QWaitCondition。
- 如何利用QTcpSocket?
- 何謂State Pattern?
- 何謂Observer Pattern?
- 何謂Chain of Responsibility Pattern?
- 如何將一個Tcl的Interpreter嵌在程式中,讓你的程式是可以接受Tcl script。 大部分的CAD產品都具備這項功能。
原則上,具備的常識為
- C++ Programming。
- Design Pattern。
- UNIX programming。 尤其是 IPO(inter process communication)。這在Qt或是其他的UI Library等需要event-driven的環境都非常常見。尤其是select()這個function更是哪裡都用。