-
QPaint 繪圖
-
模擬功能-目標
QPaint
其實 QPaint 繪圖就跟 slvs 程式庫滿像的,只需要擔心順序(圖層)問題。
用 QPaint 繪圖的話,想辦法將最新的座標 copy 進去就行了。
把繪圖的 Widget 和處理 list 的副程式獨立出來,名為 canvas.py
和 list_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 (驅動軸)的清單上,太多驅動軸就會有很多組解,可能要慢慢代入;活塞部份還沒想到怎做。
期望模擬的部份有如下效果:
-
畫出機構運動時指定點(可複數)路徑,路徑可以用線條或打點的方式繪出。
-
相關動畫的展示。
-
使用者觀看自訂角度(滑鼠在圖面上拖拉最佳)。
-
測量工具(指定點距離)。
Comments
comments powered by Disqus