顯示包含「Qt」標籤的文章。顯示所有文章
顯示包含「Qt」標籤的文章。顯示所有文章

2024年3月4日星期一

Decimal to/from Octal by Qt QString

 quint32 oct_value = 20;

QString str_oct;


// from oct to dec

str_oct.setNum(oct_value);

quint32 dec_value = str_oct.toUInt(nullptr, 8);


// from dec to oct

str_oct.setNum(dec_value, 8);

oct_value = str_oct.toUInt();


2015年8月23日星期日

X Window Desktop file for Qt Creator (BLFS 7.7)

[Desktop Entry]
Name=Qt Creator (Community)
Comment=Creator for Qt applications
Exec=/usr/bin/qtcreator
Icon=QtProject-qtcreator.png
Terminal=false
Encoding=UTF-8
Type=Application
Categories=Qt:Development;

2013年6月23日星期日

在 Ubuntu 12.04 上設定 Qt Console 除錯環境

1. 修改  /etc/sysctl.d/10-ptrace.conf 檔案:
設定 kernel.yama.ptrace_scope = 0

2. 在 QtCreator 內的 Tools --> Options --> Environment --> General, 將 Terminal 的值由 "x-terminal-emulator -e" 改為 "/usr/bin/xterm -e"

參考:
QtCreator: ptrace operation not permitted
Cannot debug console application in qt-creator

2013年3月9日星期六

Qwt 筆記 - 圖表上的 Marker 和 Picker


Plot::Plot(QWidget *parent) : QwtPlot(parent)
{
..........
..........

// marker
this->marker = new QwtPlotMarker();
this->marker->setLabelAlignment(Qt::AlignLeft | Qt::AlignBottom);
this->marker->setLabelOrientation(Qt::Vertical);
this->marker->setLineStyle(QwtPlotMarker::VLine);
this->marker->setLinePen(QPen(Qt::yellow, 2, Qt::SolidLine));

this->marker->attach(this);

// picker
this->picker = new QwtPlotPicker(this->canvas());
this->picker->setStateMachine(new QwtPickerPolygonMachine());

this->picker->setRubberBandPen(QColor(Qt::yellow));
this->picker->setRubberBand(QwtPicker::NoRubberBand);

QObject::connect(this->picker, SIGNAL(moved(QPoint)), this, SLOT(picker_moved(QPoint)));

..........
..........
}

void Plot::picker_moved(QPoint pos)
{
..........
..........

        double xTop = this->invTransform(QwtPlot::xBottom,pos.x());
        double yLeft = this->invTransform(QwtPlot::yLeft, pos.y());

        this->marker->setValue(xTop, yLeft);

        // update the screen
        this->replot();
   
        ..........
..........
}

Qwt 筆記 - 更改軸標示 (axis label) 的顏色


QwtText title(titlename); // titlename = 名稱
title.setColor(Qt::red); // 例子: 紅色
pLogPlot->setAxisTitle(QwtPlot::yLeft, title);

Qwt 筆記 - 在同一圖表上顯示不同比例的曲線


如果有兩條曲線的 Y 方向的資料範圍相差很大 (例如: 一條是 0-100, 另一條是 0-10000), 假如它們同時顯示同一個圖表上, 那麼我們會看不見範圍小的曲線的變化.
所以我們會用兩個不同的 Y 軸來處理:

QwtPlot *pLogPlot;
QwtPlotCurve *pFirstCurve, *pSecondCurve;
..........
..........
// First curve
pLogPlot->setAxisScale(QwtPlot::yLeft, pFirstCurve->minYValue(), pFirstCurve->maxYValue());
pFirstCurve->setYAxis(QwtPlot::yLeft);
pLogPlot->enableAxis(QwtPlot::yLeft, true);

// Second curve
pLogPlot->setAxisScale(QwtPlot::yRight, pSecondCurve->minYValue(), pSecondCurve->maxYValue());
pSecondCurve->setYAxis(QwtPlot::yRight);
pLogPlot->enableAxis(QwtPlot::yRight, true);
..........
..........

功能說明參考:
QwtPlot::enableAxis
QwtPlot::setAxisScale
QwtPlotItem::setYAxis

Qwt 筆記 - 更改 Qwt 圖表上軸線標示的顯示方式


QwtPlot 預設是將輸入的數值 (double 類型) 用 QLocale::system().toString() 來轉換為文字再繪畫出來 (參考 QwtAbstractScaleDraw::label 的說明)
若需要更改標示的顯示方式 (例如: 時間軸的顯示), 我們可以先建立一個承繼 QwtScaleDraw 的 class, 再重寫 label() 功能:

class TimeAxis : public QwtScaleDraw {
public:
explicit TimeAxis();

// override label function
QwtText label(double offset) const;
};

QwtText TimeAxis::label(double offset) const {
// starting time
QTime time(0, 0, 0);

    time = time.addSecs(offset);

    return QwtText(time.toString("hh:mm:ss"));
}

然後用 QwtPlot 的 setAxisScaleDraw() 功能來設定新的軸:

LogPlot::LogPlot(QWidget *parent) : QwtPlot(parent)
{
    this->pTime_axis = new TimeAxis();
    this->setAxisScaleDraw(xBottom, this->pTime_axis);
}

Qwt 筆記 - 在 Ubuntu 安裝 Qwt 開發工具 (DEB 版本)


Qwt 是一個用來繪畫圖表的 Qt 程序庳. 雖然在網上有不少文章教大家如何用 Qwt 的源碼來安裝, 不過如果你不需要最新版本, 其實你可以直接安裝 DEB 版本:

sudo apt-get install libqwt-doc
sudo apt-get install libqwt-dev

完成後你便可以使用 Qwt, 同時也可以在 QtDesigner 看到 Qwt 的元件.

2013年2月4日星期一

將一個小型 Qt5 Win32 (MSVC 版本) 程序放到另一台電腦上

要將一個小型 Qt5 Win32 (MSVC 版本) 程序放到另一台電腦上執行, 除了程序本身外, 我們也需要複製以下 DLL:

icudt49.dll (在 ICU 49 套件內)
icuin49.dll (在 ICU 49 套件內)
icuuc49.dll (在 ICU 49 套件內)
libEGL(d).dll (在 Qt5 的資料夾內的 msvc2010\lib 內)
libGLESv2(d).dll (在 Qt5 的資料夾內的 msvc2010\lib 內)
msvcp100(d).dll (在 Windows 的 System32 內)
msvcr100(d).dll (在 Windows 的 System32 內)
Qt5Core(d).dll (在 Qt5 的資料夾內的 msvc2010\lib 內)
Qt5Gui(d).dll (在 Qt5 的資料夾內的 msvc2010\lib 內)
Qt5Widgets(d).dll (在 Qt5 的資料夾內的 msvc2010\lib 內)
/platforms/qminimal(d).dll (在 Qt5 的資料夾內的 msvc2010\plugins\platforms 內)
/platforms/qwindows(d).dll (在 Qt5 的資料夾內的 msvc2010\plugins\platforms 內)

(d) 代表 debug 版本

留意 qminimal 和 qwindows 必須放在 platforms 子資料夾內, 否則程序會報錯.

安裝 Qt5 for Win32 (MSVC 2010 版本)

在安裝 Qt5 for Windows 32 bit (VS 2010 Version) 之前, 我們需要先安裝以下軟件:

1. Microsoft Visual C++ Express 2010
在這裡下載 Microsoft Visual C++ Express 2010 並安裝, 然後再安裝有關 Patch 和 Service Pack.
因為我們需要 VC++ 的 Compiler 和 Linker.

2. Windows Software Development Kit (SDK)
在這裡下載 Windows SDK, 然後安裝有關 Debugger (CDB) 的軟件

3. 由於 Qt Core 會用 ICU 的 DLL, 如果你需要將你的程序放到其他電腦上執行的話, 那麼請下載 IUC 49 套件.

4. 完成上面的步驟後便可以安裝 Qt5 for Windows (VS 2010) 了

5. 當然, 如果你需要將你的程序放到其他電腦上執行的話, Dependency Walker 一定少不了


2012年11月25日星期日

Qt QListWidget


在 QListWidget 內增加一個新的 QListWidgetItem 時我會用 addItem(), 但刪除時卻要用 findItems() 及 delete, 例如:

QList search_result = list->findItems(targettext, Qt::MatchExactly);
int total = search_result.count();
for(int i=0; i delete search_result.at(i);
}

QT QThread


當我們使用 QT 中的 QThread class 時, 目的就是將一部份工作放到另一條 thread 上. 當完成編程後並執行程序時會發生 Qt 回報要用的 object 不在此 thread 上.
經過網上"爬文"及多次實作後, 我的見解是 QT 中的 QThread class 的作用好像網絡上的 switch 一樣:

1.
   - 啟動一條新 thread (現在我稱為 "子thread")
   - 作為產生 QThread 的 thread (現在我稱為 "主thread") 與 "子thread" 的資料交換介面
 
   例如:
   class testThread : public QThread {
       Q_OBJECT
     
   private:
       MyObject       *a, *b;
         
   protected:
  void run();
 
   public:
       explicit testThread(QObject *parent = 0);
     
       void startthread();
       int getValue();
   }
 
   int testThread::getValue() {
       return this->a->value;
   }
 
   void testThread::startthread() {
        // start a new thread
        this->start();
   }
 
   void testThread::run() {
        this->b = new MyObject();
       
        while(1) {
            this->a->value = this->b->value;
            b->inc();
        }
   }
 
   void main()  
   {
       testThread  test;
     
       test.startthread();
       .....
       cout << test.getValue();
   }
 
   在以上的程序中, 你會發現在 run() 中會出以下代碼:
   this->a->value = this->b->value;
 
   這是因為 object "this->b" 和 "this->a" 是在不同的 thread 內:
   - "this->b" 在 "子thread" (沒錯, 所有在 run() 內所產生的物件都是在 "子thread")
   - "this->a" 在 "主thread"
 
   所以,對於外部讀取資料要求時,我們實作時需要間接的方式來讀取"子thread"的物件, 否則會出現報警.
 
2. 對於讀取資料, 在 Qt 內我們會經常用 Signal and Slot 功能. 但我們要留意 "子thread" 有自己的 event loop. 所以我認為做法是:
   - 準備 "子thread" 的 event loop class (sub-class QEventLoop)
   - 在 run() 中產生 "子thread" 的 event loop 物件
   - 將 "子thread" 的 event loop 的 Signal 接到 QThread 的 Slot (main event loop)
   - 再將 QThread 的 Signal 接到其他的 Slot
 
   簡單來說 QThread 的 Signal 及 Slot 的作用就如網絡上的 switch/hub, 將 "子thread" 和 "主thread" 連在一起.
 
   例如:
   class threadEventLoop : public QEventLoop {
       Q_OBJECT
       .....
   private:
       int cnt;
     
   signals:
       void newValue(int value);
 
   public slots:
       void time_out();  
   }
 
   void threadEvent::time_out() {      
       cnt++;
       emit newValue(cnt);
   }
 
   class testThread : public QThread {
       Q_OBJECT
       ....
   protect:
       void run();
     
   signals:
       void newValue(int value);
     
   public slots:
       void receive_newValue(int value);
     
   }
     
   void testThread::run() {
       int b = 0;
     
       threadEventLoop loop;
       QTimer *timer = new QTimer();
     
       QObject::connect(timer, SIGNAL(timeout()), &loop, SLOT(time_out()));
       // 將 "子thread" 的 event loop 的 Signal 接到 QThread 的 Slot
       QObject::connect(&loop, SIGNAL(newValue(int)), this, SLOT(receive_newValue(int)));
     
       timer->start(1000);
     
       // start event loop
       loop.exec();      
   }
 
   void testThread::receive_newValue(int value) {
       // 將 "子thread" 的資料傳給其他 thread
       emit newValue(value);
   }

Qt MetaType


在 Signal and Slot 功能中, 如需要傳送自行定義的資料結構 (enum, struct, 等等), 在建立 connection 前我們先需要用 qRegisterMetaType 來註冊有關資料結構

Qt Drap and Drop


當我們在 Drap and Drop 中用到 QMimeData 時, QMimeData 的 formats() 傳回的值需要和 QAbstractItemModel 的 mimeTypes() 傳回的值一致