搜尋此網誌

顯示具有 Qt 標籤的文章。 顯示所有文章
顯示具有 Qt 標籤的文章。 顯示所有文章

2011年11月4日 星期五

如何紀錄一個矩形區塊(rb)在一個矩形範圍(ra)的相對位置 ,並依比例還原至絕對位置及範圍

A. 紀錄相對位置及範圍
1. 利用 QPointF 分別紀錄rb在ra當中的左上角的點,與右下角的點的相對位置
ex:

   // 假設變數定義如下
   // s_topleft_x  (rb 左上角x在ra的絕對位置)
   // s_topleft_y  (rb 左上角y在ra的絕對位置)
   // s_bottomright_x  (rb 右下角x在ra的絕對位置)
   // s_bottomright_y   (rb 右下角y在ra的絕對位置)
   // picWidth    (ra的寬)
   // picHeight   (ra的高)
   
   QPointF topPF = QPointF((double)s_topleft_x/picWidth, (double)s_topleft_y/picHeight);
     QPointF bottomPF = QPointF((double)s_bottomright_x/picWidth, (double)s_bottomright_y/picHeight);
   
2. 設定 QRectF
ex:
    QRectF newRect(topPF, bottomPF);
   
   
以上newRect就記錄了rb在ra中的相對位置及範圍了


B.還原相對位址

  // 假設變數定義如下
  // newPicWidth  (欲還原ra的寬)
  // newPicHeight (欲還原ra的高)
  // newRect (之前紀錄的rb的相對位置的矩形範圍) 
 
  QRect mRect;
    mRect.setX((int)(((double)newPicWidth)* newRect.x()));
    mRect.setY((int)(((double)newPicHeight)* newRect.y()));
    mRect.setBottom((int)(((doublenewPicHeight)* newRect.bottom()));
    mRect.setRight((int)(((double)newPicWidth)* newRect.right()));
 
以上 mRect 就是 rb在新的ra當中的絕對位置及範圍了

2011年9月29日 星期四

在Qt中實現多語系的功能

1. 在程式中所有要翻譯的文字都必須在 QObject::tr()之中

ex:
QMessageBox msgb(this);
msgb.setWindowTitle(tr("Illegal"));
msgb.setText(tr("Illegal product!"));
msgb.setIcon(QMessageBox::Warning);
msgb.exec();


2. 在.pro檔中,設定預計產生的翻譯檔語系名稱及其位置 (本例名稱為 test.pro)

ex:
TRANSLATIONS += ./translations/test_en.ts ./translations/test_tw.ts ./translations/test_jp.ts ./translations/test_cn.ts


3. 執行 lupdate 產生 .ts檔

ex:
lupdate test.pro


4. 使用 Qt Linguist 編輯.ts檔

5. 使用 lrelease 產生 .qm檔

ex:
lrelease ./translations/*.ts


6. copy .qm檔到你所指定的目錄

ex: cp -ax ./translations/*.qm /home/daniel/language/qm/*


7. 在主程式 main當中,依據需求載入你所需的qm檔

ex:

QTranslator translator, defTrans;
QLocale g_sysLocale;

//繁體中文
translator.load("test_tw", "/home/daniel/language/qm");
defTrans.load("qt_zh_TW", "/home/daniel/language/qm");

app.installTranslator(&translator);
app.installTranslator(&defTrans);
g_sysLocale = QLocale(QLocale::Chinese, QLocale::Taiwan);

// 簡體中文
/*
translator.load("test_cn", "/home/daniel/language/qm");
defTrans.load("qt_zh_CN", "/home/daniel/language/qm");
app.installTranslator(&translator);
app.installTranslator(&defTrans);
g_sysLocale = QLocale(QLocale::Chinese, QLocale::China);
*/

QLocale::setDefault(g_sysLocale);
MainWindow mainWin(0);
mainWin.setLocale(g_sysLocale);
mainWin.start();
return app.exec();


8. 所有包在 QObject::tr()中的字串,就會依照所載入的qm檔,做文字置換動作

2011年9月19日 星期一

如何在QT中將QVariant轉換成定義在QtGui中的資料型態 (如 QColor...等),或自定型別

因為QVariant是QtCore庫的一部分,它不能夠提供定義在QtGui當中的類型(如 QColor)的轉換
如要轉換,方法式將其轉換至指定的樣版型別,如下所示,(PS:自訂型別方法相同):

QColor color = variant.value();

不過在轉換之前最好先用canConvert()的函式來檢查是否可提供該型別轉換,如下所示:

if (variant.canConvert()) {
QColor color = variant.value();
}

反向轉換(如把QColor轉成QVariant)則和一般的型態(非定義在QtCui或自訂型別)是一樣的

2011年6月14日 星期二

在QT中如何在QApplication中攔截X11 的事件

1. 繼承 QApplication, 並改寫 x11EventFilter virtual function .


class NewApplication : public QApplication
{
Q_OBJECT

public:
NewApplication(int& argc, char ** argv);

virtual bool x11EventFilter(XEvent *event);

private:

};



bool NewApplication::x11EventFilter(XEvent *event)
{
switch (event->type) {
case ButtonPress:
{
if (event->xbutton.button == 2) {
// 攔截中鍵 ... 寫你要的動作
}
}
case ButtonRelease:
case KeyPress:
case KeyRelease:
case MotionNotify:
};

return NewApplication::x11EventFilter(event);
}


2. 在mail裡面把建立QApplication改成建立NewApplication

QApplication app(argc, argv);

改成

NewApplication app(argc, argv);


3. start app

app.exec();

2009年11月6日 星期五

如何執行外部程式,並取得其標準輸出資料

在Qt中,要執行外部程式最容易的方法就是使用 QProcess, 並連結 readyReadStandardOutput 這個signal來取得其標準輸出.

例如,我們要在程式內部執行 ls 這個命令,並取得其結果,我們可以這麼做

// header file ----------

QProcess pls;

// cpp ------------------

connect(&pls, SIGNAL(readyReadStandardOutput()), this, SLOT(sl_readPlsOutput()));

pls.start("ls", QStringList() << "-al");

if (!pls.waitForStarted())
printf("wait for pls\n");
if (!pls.waitForFinished())
printf("wait for pls\n");

// slot -------------------
sl_readPlsOutput()
{
QByteArray tmpArray;
tmpArray = pls.readAllStandardOutput();
}

2009年10月20日 星期二

如何利用QT來取得系統設定

在Linux的環境中,大部分的設定都是標準的文字檔,那要如何取得那些設定的資料呢?
如果我們是用QT開發的話,可以用以下的方式
1. 利用QFile以文字檔的方式開啟設定檔
2. 將設定檔中的資料一行一行的讀出

範例1: 判斷系統是否存在特定型號的DVD
bool isFindDVD()
{
QFile procDVD("/proc/scsi/sg/device_strs");
if (!procDVD.open(QIODevice::ReadOnly | QIODevice::Text))
return false;

QString line;
while(1) {
line = QString(procDVD.readLine());
if (line.isEmpty()) break;
eprintf("isFindDVD = %s\n", qPrintable(line));
if ((line.contains("ATAPI")) && (line.contains("DVD"))) {
return true;
}
}
return false;
}

範例2: 取得 CPU的型號
QString cpuModel()
{
QFile procCPU("/proc/cpuinfo");
if (!procCPU.open(QIODevice::ReadOnly | QIODevice::Text))
return "";

QString line;
while (1) {
line = QString(procCPU.readLine());
if (line.isEmpty()) break;
if (line.contains("model name")) {
return line;
}
}
return "";
}

2009年6月23日 星期二

取得硬碟序號的方法

硬碟的序號重覆性並不高
所以用來當作防止產品被複製的檢查碼,是有相當的實用價值
以下為取得序號的方式

smartctl -a /dev/hda | grep Serial

以程式截取的方式如下 (qt為例)
QString LinuxSystem::getSerialNumber()
{
struct hd_driveid hd;
int ide;

ide = open("/dev/hda", O_RDONLY);
::ioctl(ide, HDIO_GET_IDENTITY, &hd);
printf("Serial number - %s\n", hd.serial_no);
close(ide);
return QString((const char *)hd.serial_no);
}