QT 學習筆記 – 導入 Dragdrop 與畫線

QT 學習筆記 – 軟體安裝與Dragdrop範例這篇文章裡,介紹了如何安裝與匯入官方的 dragdrop 範例。本文就基於前面這個例子,在一個新的 QT Application 內引入 dragdrop 的功能,並在節點間繪線。

開啟新的 QT 專案

首先開啟 QT Creator 開發環境,選擇 【檔案】–> 【新增檔案或專案】–> 【QT Widgets Application】,然後選擇適當的位置來存放專案目錄。完成後,就可以看到新的空白專案,按下執行,就可看到一個空白視窗了。

空白的 Widget App

複製 DragDrop 範例檔到新專案

上一篇文章中所導入的範例專案中,有幾個檔案是可以直接拿過來使用,這樣可以快速的加入 dragdrop 的功能。將下面幾個項目,從範例專案複製到新專案的目錄內

  • images/
  • draggableicons.qrc
  • dragwidget.cpp
  • dragwidget.h

接著在專案目錄上按右鍵,然後選擇 Add Existing Directory

新增現有檔案

然後會跳出一個對話框,來確認過濾條件,這邊直接按 OK 即可。

最後就可以看到新增的檔案,加入專案內了。

新的專案檔案表

加入新檔案後的專案仍可以編譯執行,但結果和原本的一樣,是一個空白視窗,因為我們還沒將 DragDrop 的 class 引入程式之中。接下來的部份會需要修改到一些程式碼,才能使用 drag&drop 的功能到另外的專案。

使用 DragDrop 範例,並在兩點間繪線

產生 Horizontal Layout

當加完 dragwidget 的檔案後,打開專案的表單設計畫面。從左側的 Layout 元件中,將一個「Horizontal Layout」拉到頁面中,物件名稱以預設的「horizontalLayout」即可。

建立一個 horizontal Layout

修改 mainwindow 程式

在 mainwindow.h 裡加入 DragWidget 的標頭檔與變數。

mainwindow.h 修改

在 mainwindow.cpp 裡產生新的 DragWidget 物件,放入成員變數 drag 中。然後透過 horizontal layout 的 addWidget 功能,將 drag 加入其中。

mainwindow.cpp 修改

修改到這裡,就可以試著執行看看,就可以看到 horizontal layout 中產生了 dragWidget 的圖示了。接下來,會對 dragwidget.cpp 做一些簡單修改,以簡化展式的程式碼。

修改 dragwidget 程式

先將 dragwidget.h 做如下修改。加入 paintEvent() 的 event handler,在畫面重繪時會呼叫到這個 function,我們會在裡面做畫線 / 繪字的功能。每當有畫面內容做變更時,可呼叫 update() 做畫面重繪。另外再宣告兩個 QLabel *boatIcon 與 *carIcon,在原本的 dragwidget 例子中, QLabel 物件 (也就是用來拖拉的圖示),都指定在區域變數內,這樣比較不好處理,我們將其從三個減少至兩個,並都將其指標賦予到class內變數中。

dragwidget.h 修改

 

dragwidget.cpp 的修改會較為繁瑣,這邊直接比較修改前後的差異,這樣會比較容易看出要修改的部份。下面的圖都是左邊為原始內容,右邊為修改後的。

DragWidget Constructor 修改

首先的對 constructor DragWidget() 的修改。houseIcon 被移除了,而 boatIcon 和 carIcon 被宣告在 class 內,所以也不需要再宣告。這邊主要是對Label新加了 setProperty(),指定其 “name” 的 property,這樣可以在拖拉事件發生時,可以分辨被拖拉的物件是哪一個種類的。

 

dragMoveEvent 修改

dragMoveEvent() 是在圖示拖拉中間的事件,在這呼叫 update() 以更新繪圖。

dropEvent() 修改

在 dropEvent() 我們也呼叫 update() 以更新繪圖。除此之外,在 drag Event 開始的時候,我們會將 property “name” 取出放進 stream 內。在此處的 dropEvent 再將其取出,以判定是哪個圖示被拖拉,再進行適當的指標取代,並且對新的 QLabel 也設定 name property。

mousePress 修改

在 mourePress event 一開始,也呼叫 update() 以更新繪圖。並且,會取出物件的 name property 並放入 stream 內,待 dropEvent 發生時再取出。這邊有一個要注意的是 property 的 type 是 QVariant 而非 QString,所以在取出時要存入而 QVariant,若存入 QString 會產生錯誤。

 

最後是新增的 paintEvent(),這邊用 QPainter 來進行繪圖,用 QPen 來指定寬度與顏色。透過 QPainter 的 drawText() function,在 Icon 的 位置繪出文字。再以 drawLine 在 carIcon 與 boatIcon 繪出連接線。當畫面有需要更新時 (如有 icon 進行拖拉),會在裡面呼叫 update(),接著系統就會自動呼叫這個 paintEvent() 來進行重繪。

打完收工

完上面一系列的修改後,就可以執行了。這個例子主要的特色就是圖示拉完後,線條與字都會跟著重繪。

dragdrop line and text

結語

本文的很多細節,其實是要先瞭解到之前的文章 QT 學習筆記 – 軟體安裝與Dragdrop範例 才會比較好懂,如果對這篇有不清楚的可以看一下第一篇。這一篇主要的目的,還是展示如何將 dragWidget 引入其它的程式中,然後再做一些變化,相信起頭後,後面應用就是千變萬化了。例如搭配 Timer 來將圖示隨機移動,看起來就會像有個樣子的模擬程式了。

我的模擬程式

附件

本文的範例原始碼 qt_widget

 

Leave a Reply