1. QPaint 繪圖

  2. 模擬功能-目標

QPaint

其實 QPaint 繪圖就跟 slvs 程式庫滿像的,只需要擔心順序(圖層)問題。

用 QPaint 繪圖的話,想辦法將最新的座標 copy 進去就行了。

把繪圖的 Widget 和處理 list 的副程式獨立出來,名為 canvas.pylist_process,沒什麼影響,讓主程式不會太雜亂。

Class 中宣告一個名為 update_figure 的函式,主程式要刷新時就會呼叫,並填進主程式的表單,這個函式就會將所有表單填進 self 的 object 裡,讓 paintEvent 函式讀取。

def update_figure(self, table_point, table_line,
        table_chain, table_shaft,
        table_slider, table_rod,
        table_style, zoom_rate):
    self.Xval = []
    self.Yval = []
    zoom = float(zoom_rate.replace("%", ""))/100
    self.table_point = table_point
    ...
    self.update()

之所以這樣寫,是因為 paintEvent 函式和所有 Qt 的 Event 函式都不能輸入 event 以外的參數。

而且 Qt 有規定 QPainter 只能畫在 paintEvent 函式中,不然會出錯。而這個函式也同時決定重新繪製的時機(視窗縮放,改變大小時)。

若想手動刷新,對 Widget 物件下 self.update()self.repaint()(不建議,閃爍頻率高)就行了。

event 參數是專門傳入事件發生相關的數據,如滑鼠座標:

def mouseMoveEvent(self, event):
    if self.drag:
        self.origin_x = event.x()
        self.origin_y = event.y()
        self.update()

能夠繪圖後,必須校正視圖的大小和位置,由於大小要看這個機構的基本尺寸是多少,所以給使用者自己調整是最好的方法了。

預設是將座標尺度放大兩倍後定義為畫布的一倍,所以剛才的 update_figure 中有下列轉換式:

for i in range(table_point.rowCount()):
    self.Xval += [float(table_point.item(i, 1).text())*zoom*rate_all]
    self.Yval += [float(table_point.item(i, 2).text())*zoom*rate_all*(-1)]

Y 軸座標乘上負號是因為不論 Window 和 Widget,兩者都是從「標題欄」往下延伸的,所以向下是負值。

上次更新中加入沒用到的 QSlider 滑桿,這次讓它能夠定義放大的倍率,從 50% 到 500%,應該都能夠支援幾乎所有尺度的機構了。

另外調整畫布大小可以用 Ctrl + 滑鼠滾輪調整,Ctrl + 左鍵按住拖移或雙擊可以定義原點位置。

這樣設定是讓使用者不會亂拉將圖面移走,也更能知道機構樣貌。

而這次顏色設定暫時只有 R、G、B 三色,其他色碼的加入還要看下說明文件,原本的顏色都偏亮或太黯淡,所以會整合後加入其他顏色。

*上次的 mpl 畫布就有加入存成 png 圖片的功能了,想不到現在 QPainter 也能如法炮製。

好像大部分 Widget 都能用這個方式截圖,不過 OpenGL 不知道可不可行。

fileName, sub = QFileDialog.getSaveFileName(self, 'Save file...', '../', 'PNG file(*.png)')
if fileName:
    fileName = fileName.replace(".png", "")
    fileName += ".png"
    pixmap = self.mplWindow.grab()
    pixmap.save(fileName)

模擬功能

主要關鍵都在 Drive Shaft (驅動軸)的清單上,太多驅動軸就會有很多組解,可能要慢慢代入;活塞部份還沒想到怎做。

期望模擬的部份有如下效果:

  1. 畫出機構運動時指定點(可複數)路徑,路徑可以用線條或打點的方式繪出。

  2. 相關動畫的展示。

  3. 使用者觀看自訂角度(滑鼠在圖面上拖拉最佳)。

  4. 測量工具(指定點距離)。


Comments

comments powered by Disqus