無野好玩, 走去學人寫 Qt....就係為左想改個 GRBL Controller....係咪痴痴地呢?
基本資料:
Qt class hierarchy
睇完個圖就識用? 我話 "係", 你吹得我漲咩?
其實如果你有寫開 C++, 基本上都睇得明, 反而都係用一堆 library 做野, 有問題都係即搵.
至於個 project 既架構, 點樣用 Qt gen 個 executable 出黎, 點埋睇下就知了.
之後改野, 如果唔係大改動既, 搵下 D code, 改少少野, 識 C++ 都夠用既.
要 Compile 到 GRBL Controller, 需要有少少改動, 而且未必個個 version 一樣, 以下係一個例子:
(只限於 Windows 下使用以下版本, 其他版本唔敢包. 因為未必人人有裝 VS, 所以無用 VS 版本.)
1) Qt version: Qt 5.5.0 for Windows 32-bit (MinGW 4.9.2, 959 MB)
下載版面 ,
直接下載
2) GRBL Controller 3.6.1
下載版面 ,
直接下載
下載完先安裝好 Qt 5.5.0, 唔理咁多, 乜都裝哂佢.
之後爆開 GRBL Controller 既 source, 再用 Qt 5.5.0 去開.
假設 GRBL Controller 放左去: E:\my.Source\GrblHoming\GrblHoming-3.6.1
最好改下 build 既 path, 左手邊 Projects 入面, 改左 General 下面既 path, 記得改哂 Debug 同 Release.
之後直接 Run 既話, 會出 error (人地都放埋 exe 比人下載, 無理由咁, 唔知係咪其他版本會無事.)
需要改動好系, 只係加番句 #include <QtCore/QObject> 去下面兩個 header file 就得了:
- Headers\timer.h
- log4qt\Headers\helpers\factory.h
之後應該行到無事, 但仲有可能 debug 唔到. 原因出在 qextserialport 度.
參考資料:
Issue 158: On Windows7, QextSerialEnumerator::getPorts() occur debug break
好似有地方唔記得 check
INVALID_HANDLE_VALUE, 直接行 RegCloseKey 就會出事.
解決方法 (修改 Sources 入面 qextserialenumerator_win.cpp:
1) 在 getRegKeyValue 中, 如果提供的是 invlalid handle 就即走
static QString getRegKeyValue(HKEY key, LPCTSTR property)
{
/* By Super169
* Return empty string for invalid handle
*/
if (key == INVALID_HANDLE_VALUE) return "";
:
:
}
2) 在 getDeviceDetailsWin 中, check 下 get 番黎既 key 係咪 invalid
static bool getDeviceDetailsWin(QextPortInfo *portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData
, WPARAM wParam = DBT_DEVICEARRIVAL)
{
:
:
HKEY devKey = ::SetupDiOpenDevRegKey(devInfo, devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
/* By Super169
* Return false for invalid handle
*/
if (devKey == INVALID_HANDLE_VALUE)
return false;
3) 在 enumerateDevicesWin 中, check 下 無問題 而且有名既 port 至加落去個 list 度
static void enumerateDevicesWin(const GUID &guid, QList *infoList)
{
HDEVINFO devInfo;
if ((devInfo = ::SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT)) != INVALID_HANDLE_VALUE) {
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for(int i = 0; ::SetupDiEnumDeviceInfo(devInfo, i, &devInfoData); i++) {
QextPortInfo info;
info.productID = info.vendorID = 0;
/* By Super169
* Skip for invalid devices, or empty name
*/
if ( getDeviceDetailsWin(&info, devInfo, &devInfoData) &&
info.portName.compare("") &&
!info.portName.startsWith(QLatin1String("LPT"), Qt::CaseInsensitive) )
infoList->append(info);
}
::SetupDiDestroyDeviceInfoList(devInfo);
}
}
做左以上幾樣 (第 1 個係 optional, 只係想安全 D), 應該可以 debug 到, 而且唔會出埋 D 無用既 list 了.
之後可以開始進行改動了.
so far 我只係改左個 combo box 既 behaviors, 唔要 auto-complete, 同埋加左兩個 button 改左 step 既設定, 都唔算大工程, 識少少 C++ 都夠了.