QOpenGLWidget

      在〈QOpenGLWidget〉中尚無留言

OpenGL 是目前繪制3D動畫的翹楚。早期雖有微軟的 DirectX 與之竸爭,但 DirectX 只支援微軟的 Windows,而OpenGL則支援所有系統,包含了 Linux,Mac 及 Windows。 所以OpenGL硬生生的將 DirectX 打趴掉,再加上nVidia全力支援 OpenGL,造就了現今OpenGL一支獨秀的局面。

另外,OpenGL是Open Source, 任何人都可以使用,這讓微軟的 DirectX更加灰頭土臉。

簡介

QLabel就可以直接使用 setPixmap()將圖片顯示出來了,那為何還需要使用OpenGLWidget呢!! 這是因為OpenGLWidget可以直覺的繪製具有Z軸的 3D 影像,而QLabel只能繪製2D圖形。再加上QOpenGLWidget是採用GPU(外接顯卡)硬体加速繪製,其效能遠高於QLabe的CPU 演算。

QtDesigner裏雖然有OpenGLWidget元件,但不可以直接加入使用。只能在QtDesigner UI設計中先加入QFrame,然後在Python中自行定義 QOpenGLWidget子類別,然後動態加入。其原因是我們必需自行覆寫 paintGL()方法,如下所示

from PyQt5.QtCore import QPoint
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QOpenGLWidget
from MahalCv import MahalCv as cv

class MahalGl(QOpenGLWidget):
def __init__(self,parent = None):
super().__init__(parent)
self.img=cv.read('buddha.jpg')
self.img=cv.resize(self.img, 800,600)
self.angle=0
def paintGL(self):
img = cv.cv2qimage(cv.rotation(self.img, self.angle))
paint = QPainter()
paint.begin(self)
paint.drawImage(QPoint(0,0),img)
paint.end()
self.angle=(self.angle+6)%360
self.update()

class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
layout=QVBoxLayout(self.frame)
self.mahalGl=MahalGl()
layout.addWidget(self.mahalGl)

paintGL(self)是第一次show,每次 resize或是調用update()時就會自動觸發的方法,所以畫面若需變動時,就要先準備好圖像,然後調用paintGL() 一次。

完整代碼

底下代碥,可以在 PyQt5裏,將圖片一直旋轉

import sys
from PyQt5.QtCore import QThread, pyqtSignal, QPoint
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QMainWindow, QApplication, QVBoxLayout, QOpenGLWidget
from MahalGl import MahalGl
from ui.ui_mainwindow import Ui_MainWindow
from MahalCv import MahalCv as cv
class MahalGl(QOpenGLWidget):
def __init__(self,parent = None):
super().__init__(parent)
self.img=cv.read('buddha.jpg')
self.img=cv.resize(self.img, 800,600)
self.angle=0
def paintGL(self):
img = cv.cv2qimage(cv.rotation(self.img, self.angle))
paint = QPainter()
paint.begin(self)
paint.drawImage(QPoint(0,0),img)
paint.end()
self.angle=(self.angle+6)%360
class PaintThread(QThread):
callback=pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.runFlag=True
def run(self):
while self.runFlag:
self.callback.emit()
QThread.msleep(1)
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
layout=QVBoxLayout(self.frame)
self.mahalGl=MahalGl()
layout.addWidget(self.mahalGl)
self.thread=PaintThread()
self.thread.callback.connect(self.refresh)
self.thread.start()
def refresh(self):
self.mahalGl.update()
if __name__=='__main__':
app=QApplication(sys.argv)
frame=MainWindow()
frame.show()
app.exec()

底下的圖片,會一直旋轉

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *