QT學習筆記
1.對象樹:在Qt中,每個 QObject 內部都有一個list,用來保存所有的 children,還有一個指針,保存自己的parent。當它自己析構時,它會將自己從parent的列表中刪除,并且析構掉所有的children。
我們需要顯試刪除(就是用DELETE刪除)的對象是那些使用NEW創建的并且沒有父對象的對象(切記是new的才要delete,通過成員函數獲得的對象,沒有特殊說明的,千萬不要隨便delete.)。如果我們在刪除一個對象的父對象之前刪除它,QT會自動地從它的父對象的子對象列表中移除它的
2.什么是回調函數?
回調函數就是把函數的地址作為參數傳入另一個函數
回調函數就是一個通過函數指針調用的函數。
① 函數指針的作用:首先,函數指針可以在不同時間傳遞不同函數的地址,即在不同的時間使用不同的函數,如果不用函數指針只能順序執行函數。
注:信號與槽的槽函數中使用匿名函數或函數指針時時可以考慮使用蘭姆達表達式。
QT資源文件使用格式:
“:+前綴+文件名”
QtMainWindow
MenuBar是菜單欄,toolbars是工具欄,Dock Widgets是小窗口,Central Widget是中央窗口,Status Bar是狀態欄
QWidget? QMainWindow? QDialog類的區別:
QWidget類是所有用戶界面對象的基類。 窗口部件是用戶界面的一個原子:它從窗口系統接收鼠標、鍵盤和其它事件,并且在屏幕上繪制自己的表現。每一個窗口部件都是矩形,并且它們按Z軸順序排列的。一個窗口部件可以被它的父窗口部件或者它前面的窗口部件蓋住一部分。
QMainWindow 類提供一個有菜單條、錨接窗口(例如工具條)和一個狀態條的主應用程序窗口。主窗口通常用在提供一個大的中央窗口部件(例如文本編輯或者繪制畫布)以及周圍菜單、工具條和一個狀態條。QMainWindow常常被繼承,因為這使得封裝中央部件、菜單和工具條以及窗口狀態變得更容易。繼承使創建當用戶點擊菜單項或者工具條按鈕時被調用的槽成為可能。你也可以使用Qt設計器來創建主窗口。
QDialog類是對話框窗口的基類。對話框窗口是主要用于短期任務以及和用戶進行簡要通訊的頂級窗口。QDialog可以是模式的也可以是非模式的。QDialog支持擴展性并且可以提供返回值。它們可以有默認按鈕。QDialog也可以有一個QSizeGrip在它的右下角,使用setSizeGripEnabled()。
QDialog 是最普通的頂級窗口。不被嵌入到一個父窗口部件的窗口部件被叫做頂級窗口部件。通常情況下,頂級窗口部件是有框架和標題欄的窗口(盡管如果使用了一定的窗口部件標記,創建頂級窗口部件時也可能沒有這些裝飾。)在Qt中,QMainWindow和和不同的QDialog的子類是最普通的頂級窗口。摘自CSDNQWidget,QMainWindow和QDialog的區別ikahn的博客-CSDN博客qmainwindow和qdialog
模態和非模態對話框
非模態對話框是對話框后面的其他對話框或窗口依然可用
模態對話框是對話框后面的其他對話框或窗口不能操作? 只能先操作當前的對話框
如果從線程角度來講,模態對話框實際上是線程阻塞的,也就是子對話框是一個線程,但是在創建這個子線程之后,父窗口就阻塞了;而非模態對話框則不是阻塞型的線程模型,父子線程可以并行運行。
過程:
1 新建一個dialog
2 利用dialog 成員函數 指定窗體大小? 顯示窗體(非模態)
3 模態:
方式1 :exec()函數 阻塞函數 如果沒有關閉窗口 程序會停在這里不會向下運行
方式2 :dialog成員函數 setModal(true)? 再顯示窗體
需要繼續加一個函數delete相應的New(因為只有主窗體關閉時才自動釋放? 子窗口創建的對話框需要手動釋放)
dialog->setAttribute(Qt::WA_DeleteOnClose)
8種標準對話框:
功能 按下按鍵彈出對應的對話框(顏色對話框、文件對話框、字體對話 框、輸入對話框)
1 利用信號與槽的操作,右鍵UI中的按鍵創建出槽函數,填充即可
2 顏色對話框需要包含頭文件QColorDialog
在槽函數中實現顏色對話框? 用類創建一個對象
靜態函數方式實現:QColor color = QColorDialog::getColor(Qt::red,this);
qDebug顯示一下color
3 在槽函數中實現文件對話框 文件對話框需要包括QFileDialog
搜索手冊發現他也是有靜態成員函數,省去了用類創建對象再調用函數的過程
與上面類似,QString filename = QFileDialog::getOpenFileName(this,"OpenFile(顯示內容)",“C:\”,"圖片文件(*.png *.jpg)");
qDebug顯示一下
4 字體對話框 include<QFontDialog>
與上面一樣,函數為getFont(bool類型的指針,this); 返回QFont類型的變量
if(ok)
ui->pushButton_3->setFont(返回的變量);
5 輸入對話框<QInputDialog>
仿照上面的寫法 靜態成員函數有好幾個 手冊上可以看?
例如getText(this,“輸入的title”,"提示",QLineEdit::Normal,"什么都不敲顯示的默認字符",bool類型的是否敲入);返回值QString類型變量
測試輸入整數getInt(...)
6 消息對話框<QMessageBox>
question函數? 問題對話框
information函數: 提示對話框
warning函數:警告對話框
critical函數:錯誤對話框
about函數:關于對話框
7 進度對話框<QProgressDialog>
定義指針的話,需要開辟空間,只有mainWindow關閉的時候才會回收空間
創建對象的話,函數結束對象就結束了。對象的構造函數里要加一些東西
成員函數:setWindowTitle("string") 窗口名設置
show() 顯示? ? setWindowModality(Qt::WindowModal)變為模態
prodlg.setValue(i)
if(prodlg.wasCanceld())? break;
prodlg.setValue(50000) 輸出結束
多線程:大文件復制拷貝時,可以繼續做其他的事情。增加函數調用,QCoreApplicaion::processEvents();
8 錯誤信息對話框<QErrorMessage>
創建對象 不對? ? (why?? 因為創建對象的話函數結束就釋放了,再點擊一次相當于重新創建對象,無法保存上次的設置)
用指針開辟空間? 把其放在mainWindow里
9 向導對話框<QWizard>
16 按鈕控件組 button
控件和布局學習
Buttons是一個按鍵組,
push Button 過。
(1)tool button 工具按鈕,多以圖形或圖標方式出現,如QQ頭像。
流程:1 添加資源文件 加一張圖片? 把圖片加到tool button按鈕上
2.代碼方式添加:ui->toolButton->setIcon(QIcon(":+前綴+文件名"))?
3.添加文本并更改顯示方式(toolButtonStyle)
4.autoRise
(2) Radio Button,選擇相關按鈕 幾選一,有點像投票的選項(單選)
運行時有默認選項功能(代碼實現)
ui->radioButton(也可以改成別的)->setCheck(true);
流程:一年級 二年級 三年級? 分數分檔次, 選中<60分時用信號和槽的功能實現打印信息 不及格
(3) Group Box
用來分組
(4) check Box 多選
List Widget? 列表選擇
Item views(model-based)適用于大量數據的操作
Item Widgets(item-based)比較簡單
代碼:
listWidget 添加內容,用addItem或addItems函數
addItem(指針or字符串)
用QListWigetItem指針方式的構造函數
(List是一個容器)
文字對齊:指針->setTextAlignment()? 助手中查看該函數的使用方法
用addItems()函數 一次添加多行
Tree Widget
1 創建列:
代碼實現:ui->treeWigdet->setHeaderLabel()
用到QStringList? 可以試試創建匿名對象
2 創建樹
代碼:ui->treeWidget->addTopLevelItem();
用到QTreeWidgetItem 指針
3 添加圖標? setIcon
4 添加分支 指針->addChild();
Table widget控件
建立控件 √
設置行列(setColumnCount/setRowCount) √
設置頭標簽(setHorizontalHeaderLabels) √
填充內容(setItem)? 用循環 先填第一列 再填后邊的列 通過QString類里的number函數將int類轉換為字符串
Containers控件
Group Box 分組
Scroll Area 滾動區域
Tool Box 類似QQ分組
Tab Widget 類似選項卡
Stacked Widget 棧 可以把其他控件放在里邊? QStackedWidget提供了一個控件棧,在這個棧中,一次只能顯示一個控件。
用按鍵切換的方式換頁復習一下蘭姆達表達式的相關知識 實現按鈕信號與槽的功能? 輸出一些字。再實現按下按鈕切換到相應頁面的功能 (setCurrentIndex函數)
InputWidgets控件
combo box 下拉列表? 通過addItem函數添加選項
Font Combo Box 選擇字體? 信號與槽實現字體的選擇
LineEdit? 一行 用于輸入姓名或者密碼之類
Text Edit 和Plain Text Edit的區別:TE可以編輯字體 設計格式 PTE是單純的文字沒有別的
SpinBox、DoubleSpinBox: 數字增減
TimeEdit、DateEdit、Date/Time Edit? 設置時間、年月日。例如:顯示系統時間,利用setTime函數? 需要創建一個QDateTime類型的對象,這個對象用該類里的函數currentDateTime()
Dial :旋鈕 改變數值
H/V scroll Bar? 水平條和縱向條
H/V Silder 調整值
自定義控件
1 添加Qt設計師界面類 widget
2 ui中添加widget容器 右鍵提升為 添加上面創建的類的名稱
3 關聯兩個控件:
4.添加按鍵? 獲取當前值
添加函數? 返回ui->spinBox中的value值 用信號與槽關聯按鈕與自定義的控件
Label控件
功能:1 顯示字符串
2 顯示圖片信息setPixmap 改變圖片大小:setScaledContents
3 添加動圖 setMovie 顯示動圖 對象->start
事件 --鼠標事件
1 捕獲事件是否產生:通過調用QApplication里對象a的函數a.exec()
2 事件過濾
3 事件分發
4 事件處理
先聲明 再定義鼠標點擊事件
常用鼠標處理事件:
mousePressEvent
mouseReleaseEvent
mouseDoubleClickEvent
例如:雙擊時設置為全屏? 用到函數windowState
全屏:Qt::WindowFullScreen
設置窗體狀態:setWindowState()
mouseMoveEvent
wheelEvent
定時器
兩種使用方法:
方法一:
1 包含頭文件QTimer? 然后創建一個該類型的指針 開辟空間?
2 函數使用start設置定時時間
3 connect設置聯系? 用到QTime::timeout,和蘭姆達表達式 設置label里的內容 +1
方法二:(事件)
用定時器的事件,事件到來時用定時器處理函數
1 調用函數startTimer(定時時間) 該函數返回一個timer的編號 可以利用返回值用到不同的timer
2 重新編寫timerEvent函數? 同上
3? 在類中設置不同的timer id? 然后考慮兩種不同時長情況下的變化
事件分發
個性化處理
串口調試助手
功能:1.軟件打開時識別出可用串口? 放在下拉列表中
第一步:在pro文件中加入 QT +=serialport
第二步:添加頭文件
第三步:設計UI? 顯示串口號
第四步:代碼初始化。設置窗口大小、設置標題
第五步:由于軟件運行時要周期性掃描,因此定義一個定時器,創建定時器指針,定時,再利用信號和槽實現。需要定義一個函數,做為槽函數。
第六步:槽函數設計:foreach關鍵字? 按順序遍歷容器中的所有成員
foreach(容器里邊的類型,容器名字)
發現當前可用串口信息:QSerialPortInfo::availablePorts()
類型:QSerialPortInfo 容器:上邊的列表
此時完成了遍歷串口信息,然后通過portName得到串口名字 該函數返回Qstring類型
創建一個QStringList類型的容器,把名字放進這個容器里 初始時清空
然后把該容器添加到comboBox里
定義一個QStringList的對象 賦初值0? 然后判斷一下當前串口數量和上次的是否相等 不相等再執行添加的功能
功能2:
點擊打開串口 設置下面的參數 再點擊關閉串口
1 轉到槽 編寫槽函數
兩種情況 第一種情況是按鍵內容=打開串口
在頭文件里聲明一個私有變量? 類型是SerialPort*? 用其創建一個串口
設置串口名字 setPortName(comboBox里的當前串口名字currentText)
設置波特率:setBaudRate? 需要先把字符轉換為整型再填進去? 用到toInt函數
設置數據位:setDatabits? 用switch case語句根據不同情況選擇不同枚舉類型
設置奇偶校驗:setParity? 此時用currentIndex+swich case
停止位設置:setStopBits 仿照之前的寫法
打開串口:open(讀寫)如果打開失敗 使用QMessageBox消息對話框(記得包含頭文件)彈出消息,information(this,"錯誤提示",“串口打開失敗”,QMessageBox::OK)
最后打開后設置所有參數不能修改 用setEnable(false)
把當前的文本設置為關閉窗口
第二種情況 串口已經處于打開狀態
直接用close函數
把setEnable(false)都改為true
設置文本
優化:添加初始參數默認值
用setCurrentIndex
如何添加功能讓串口受到數據
1 UI界面創建:
添加label? 接收設置?
? ? ? ? checkBox 接收方式 ASCII碼(默認選中 用setCheckState函數)、十六進制、暫停? (只能選中一個)
添加TextEdit? 接收數據 發送數據
? ? ? ? Label 接收字節:0? 發送字節:0
2 創建信號和槽 connect(串口, readyRead, this, )
槽函數編寫:(重點)
serialPort_readyRead()
首先判斷當前模式(暫停,ASCII,16進制)
如果當前不是暫停,就讀取全部串口數據 函數:readAll? 用字符串類型接收
用字符串里的Length函數看收到了多少字節數據? 放到一個long類型的整型數據里,在當前的label里顯示(注意+=);
如果當前模式是16進制,
優化:
問題 怎么收完一組后換行??
如果當前模式是ASCII,
最后設置txetEdit顯示即可
優化:讀取前一輪數據,并追加到當前顯示中
發送功能
1 UI創建按鈕 發送 轉到槽 編寫槽函數
2 提取要發送的內容 toPlainText? 放到一個字符串中
3 用串口的函數write? 需要把字符串類型轉換為QByteArray類型。用到toLatin1函數
4 計算發送的字節長度 用lenth函數 +=一個值? 然后label中顯示
5 添加清空接收區和清空發送區的功能