使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture:續

這篇基本上是之前《使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture》一文的後續。

在當時,Heresy 有提過,如果真的用 QOpenGLPaintDevice 來給 QGraphicsScene 繪製到 Frame Buffer Object 上的話,會造成文字的破碎、無法識別的狀況;而 Heresy 當時的解法,是暫時放棄 OpenGL 繪圖,而讓 QGraphicsScene 先畫到 QImage 上(raster)、然後再把它傳到顯示當作為 OpenGL 的 texture。

理論上,這個方法的確是可行的,但是實際上,在後來使用的時候,卻發現:

當介面稍微多一些東西的時候,用 QGraphicsScene 把圖形介面畫在 QImage 上要花超過 150ms… orz

如果是一般視窗環境,或許還算勉強可以接受,但是在 VR 環境下,這樣連 10FPS 都到不了的速度,是完全無法被當作「堪用」的…

閱讀更多»

廣告

Qt OpenGL 的一些使用問題

這一篇,算是自己點單紀錄一下,目前使用 Qt 5 來開發 OpenGL 程式時,碰到的一些問題吧…

基本上,Heresy 對於整個 Qt OpenGL 的使用架構不算非常熟,也是邊寫邊摸,所以本文也不盡然正確,很大的機會應該有不少地方是使用錯誤…不過,基本上就算記錄下來,給自己以後參考用了。

首先,Qt 5 基本上應該算是已經深度整合 OpenGL/OpenGL ES 了~預設下載預先編譯好的版本,都有支援 OpenGL、而不用另外自行編譯了。

而他的主要文件,應該可以從《OpenGL and OpenGL ES Integration》這邊開始看。

閱讀更多»

使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture

從去年開始,Heresy 就有在試著用 Qt 搭配 OpenVR,開發支援 SteamVR 的虛擬實境的程式。當時在寫的時候,一部分是參考 GitHub 上的「QVRViewer」這個專案(連結),也算是成功地把 Qt OpenGL(官網)的框架,成功地和 OpenVR 整合到一定程度了。

而接下來,則是希望可以在虛擬實境的環境裡面,顯示圖形介面的部分。這部分,則是參考了 OpenVR 的「helloworldoverlay」這個範例(連結);在它裡面的「openvroverlaycontroller.cpp」這個檔案(連結)就有把 Qt 的 Widget 繪製成 OpenGL Texture、並手動傳送滑鼠事件進去的操作方法。

首先,他這邊的概念,就是透過 Qt Graphics View Framework 的框架,來繪製 QWidget;而和一般使用 QGraphicsScene 時不同的地方,是這邊不會去使用 QGraphicsView 來做呈現,而是特別去設定要使用的 QPainter,來決定要畫到哪裡。

閱讀更多»

支援科學記號的 QSpinBox

Qt 本身有提供 QDoubleSpinBox 這個元件(官網),可以提供使用者來輸入浮點數(小數),不過他基本上並不支援「科學記號」(科學記數法、Scientific notation、維基百科),所以如果要輸入極大的數字、或是相當接近 0 的小數時,都會相當麻煩。

查了一下,Qt 似乎沒有特別針對科學記號設計類似的元件,所以如果有這樣的需求,就得自己來了。

針對這個問題,網路上可以找到一些討論,也有一些實作,但是看起來好像都很複雜?

後來 Heresy 自己玩了一下,發現其實只要繼承 QDoubleSpinBox 並搭配 QDoubleValidator官網)的話,其實可以相對簡單地建立出一個支援科學記號的版本。

下面這個 QScientificSpinBox,就是一個簡單的實作:

閱讀更多»

自行使用 VisualStudio 建置 QtAV

之前在《使用 Qt 撰寫影片播放程式的一些紀錄》一文,Heresy 有大概紀錄一下使用 Qt 5.x 內建的 QMediaPlayer 來撥放影片的方法;不過當時也碰到了一些問題,所以 Heresy 後來也有試著找一些替代方案來用。

後來是發現 QtAV 這個整合了 Qt 和 FFmpeg(官網)的這個專案似乎還算不錯,所以就認真研究看看了。

QtAV 的官方網站是:http://www.qtav.org/,原始碼則是在 https://github.com/wang-bin/QtAVhttps://sourceforge.net/projects/qtav/

他基本上包含了 C++ 函式庫、對應的範例,以及兩個功能算是完整的播放軟體(C++ 與 QML)。

而由於他提供的預先編譯好的版本選擇有限,所以 Heresy 後來就開始研究怎麼自己編譯了。這篇基本上就是怎麼在 Windows 環境下,使用 Visual C++ 來進行建置的紀錄:

閱讀更多»

QWizard 傳遞自訂變數

之前有大概介紹過一下使用 Qt 的 QWizard 的使用經驗了。

而當時也有提到,在不同的 QWizardPage 之間,要交換資料的話,基本上是要靠「field」的機制來進行的,這部分的說明主要是官方的《Registering and Using Fields》這份文件(頁面)。

Qt 在這邊的設計,主要是靠 Qt 類別的預設「屬性」(property)、以及該屬性對應的存取子來做存取的。所以,當一個類別沒有指定預設要使用的屬性時,就需要透過 QWizardsetDefaultProperty() 這個函式(文件),來登記要使用的屬性名稱、以及對應的存取子。

像是之前也有提過,如果是以 QDoubleSpinBox 來說,如果想要在 QWizard 的架構下登記成 field 的話,就需要先執行下面的指令:

setDefaultProperty("QDoubleSpinBox", "value", "valueChanged");

他的第一個參數是類別的名稱,第二個參數則是要使用的屬性名稱(value),最後則是這個類別用來告知該屬性有變化的 signal(valueChanged)。

閱讀更多»

Qt 的精靈模式:QWizard

這篇算是簡單紀錄一下,怎麼用 Qt(官網)來寫出「一步一步進行下去」的精靈模式(Wizard mode)的程式。

Qt 的精靈模式,是從 Qt 4.3 開始引進的,基本上主要是兩個類別:QWizard官方文件)和 QWizardPage官方文件)來實作。

其中,QWizard 是提供精靈模式的一個大的框架(framework)、來處理整個精靈的流程;在一個精靈中,會有許多個 QWizardPage 的物件、個別代表精靈模式中的每一個頁面。

基本範例

下面就是官方給的一個極簡單的範例:

QWizard wizard;
wizard.addPage(createIntroPage());
wizard.addPage(createRegistrationPage());
wizard.addPage(createConclusionPage());

wizard.setWindowTitle("Trivial Wizard");
wizard.show();

閱讀更多»

使用 Qt 撰寫影片播放程式的一些紀錄

要使用 Qt 5 寫出一個撥放影片的程式,其實滿簡單的;因為 Qt 本身已經提供了一個「Qt Multimedia」的模組(文件),提供了以 QMediaPlayer文件)為主的類別、讓使用者可以快速地撰寫出一個撥放軟體了。

這邊 Heresy 則是記錄一下,最近使用他的一些紀錄。


基本使用

他最簡單的寫法,大概可以按照官方範例、寫成:

player = new QMediaPlayer;

playlist = new QMediaPlaylist(player);
playlist->addMedia(QUrl("http://example.com/myclip1.mp4"));
playlist->addMedia(QUrl("http://example.com/myclip2.mp4"));

videoWidget = new QVideoWidget;
player->setVideoOutput(videoWidget);

videoWidget->show();
playlist->setCurrentIndex(1);
player->play();

閱讀更多»

Boost 與 Qt 的 Signal / Slot 效能測試

Qt 這個圖形介面的開發套件(官網),基本上算是目前數一數二的跨平台圖形介面開發方案了。

在 Qt 的架構中,要在不同的物件之間傳遞資訊、觸發事件,所使用的是其創造的「Signals & Slots」架構(官方文件)。

而目前除了 Qt 之外,還有許多函式庫,也有提供 Signals & Slots 的功能,像是 Boost C++ Libraries 裡面,就有 boost::signal 和 boost::signal2 這兩個函式庫可以使用;其中,Heresy 也有針對 boost::signal2 做過介紹(參考)。

在 Heresy 來看,Qt 的 signal & slot 的架構比較麻煩的地方,是他必須要使用許多非標準的語法,所撰寫的程式還需要經過 Qt Meta-Object Compiler(moc)來做前處理,才能讓一般的 C++ 編譯器編譯。相較之下,Boost 的 Signal2 在撰寫上的彈性就比較大、也比較方便了。

不過,這兩者個效能怎麼樣呢?這邊 Heresy 就是打算來做個簡單的效能評估。

閱讀更多»

OpenNI 2 VideoStream 與 Device 的設定與使用

之前的《OpenNI 2 基本程式範例》一文,基本上是一個最簡單、OpenNI 2 讀取深度的範例;而之後的《OpenNI 2 的錯誤處理》,則是針對 OpenNI 2 所採用的錯誤處理方法,做一個補充。接下來這一篇呢,則是在《OpenNI 2 基本程式範例》中,讀取深度的範例程式的基礎上,加上彩色影像的讀取,並說明如何針對建立出來的 VideoStream 做進一步的參數設定。

而最後,也會稍微帶一下,要怎樣把 OpenNI 2 讀到的影像資料,轉換成其他函式庫,例如 OpenCV 或 Qt 專用的格式。

閱讀更多»