Qt学习笔记(持续更新)
第一個應用程序
#include "widget.h" #include <QApplication> #include<QLabel> int main(int argc, char *argv[]) {//創建qt應用程序對象QApplication a(argc, argv);//創建標簽控件QLabel label("你好");//來吧,展示label.show();Widget w;w.show();//讓應用程序進入事件return a.exec(); }Qt中文編碼問題
Qt內部編碼:
- Qt應用程序編程接口及其內部實現所使用的字符,都是以unicode編碼(UTF-16),也就是Unicode就是Qt的內部編碼
外部編碼:
- 程序源代碼中使用的字面值形式的字符和字符串、用戶通過程序界面輸入的字符和字符串,以及程序通過文件、網絡、進程間通信或其它媒介讀取的字符和字符串,受系統環境等因素的影響,通常會是各種各樣的編碼格式,一般將其統稱為外部編碼
編碼轉換
- 默認情況下,Qt5可以正確理解uft-8格式編碼,并將其自動轉換為內部的unicode編碼,如果使用utf-8的中文字符串總是能夠正確顯示,但是如果使用其它格式的外部編碼,比如windows中常用的GBK編碼,將會出現亂碼現象
- 通過QTextCodec實現編碼轉換 QTextCodec *codec =QTextCodec::codecForName(“GBK”);
- QString string = codec->toUnicode (“GBK編碼的中文字符串”);
所以我們需要盡量使用UTF8
父窗口
-創建控件時,可以指定停靠在某個父窗口上面,這時控件將作為子窗口被束縛在其父窗口的內部,并伴隨父窗口一起移動、隱藏、顯示和關閉;否則該控件將作為獨立窗口顯示在屏幕上,且游離于其它窗口之外
QWidget及其子類的對象可以做為其它控件的父窗口常用的父窗口類又如下三個∶
- QWidget
- QMainWindow(主窗口)//QWidget的直接子類
- QDialog(對話框)//QWidget的直接子類
父窗口的析構函數回自動銷毀其所有的子窗口對象,因此即使子窗口對象是通過new操作符動態創建的,可以不顯式的執行delete操作,而且不用擔心內存泄漏的問題,只要保證父窗口對象被正確銷毀,其子窗口也將隨之被銷毀
#include "widget.h" #include <QApplication> #include<QLabel> #include<QDialog> #include<QMainWindow> #include<QPushButton>int main(int argc, char *argv[]) {QApplication app(argc,argv); // QWidget parent;QDialog parent; // QMainWindow parent;parent.move(50,50);parent.resize(320,320);QLabel label("我是標簽",&parent);label.move(20,40);QPushButton button("我是按鈕",&parent); //棧對象button.move(20,100);button.resize(80,80);QPushButton* button2 = new QPushButton("我是按鈕",&parent); //堆對象parent.show();//讓應用程序進入事件return app.exec(); }信號和槽
- 信號和槽是QT自行定義的一種通信機制,實現對象之間的數據交互。當用戶或系統觸發了一個動作,導致某個控件的狀態發生了改變,該控件就會發射一個信號,即調用其類中一個特定的成員函數(信號),同時還可能攜帶有必要的參數
- 槽和普通的成員函數幾乎沒有太多區別,可以是公有的、保護的或私有的,可以被重載,也可以被覆蓋,其參數可以是任意類型,并可以像普通成員函數一樣調用
- 槽函數與普通成員函數的差別并不在于其語法特性,而在于其功能。槽函數更多體現為對某種特定信號的處理,可以將槽和其它對象信號建立連接,這樣當發射信號時,槽函數將被觸發和執行,進而來完成具體功能
信號的定義:
信號的定義 class XX:public QObject { Q_OBJECT signals:void signal_func(..);//信號函數 };信號函數只需聲明,不能寫定義
槽的定義:
信號和槽的連接:
QObject::connect( const QObject * sender, const char * signal const Qobject * receiver, const char * method) ; 參數: sender:信號發送對象指針 signal:要發送的信號函數,可以使用“SIGNAL(..)”宏進行類型轉換 receiver:信號的接收對象指針 method:接收信號后要執行的槽函數,,可以使用“SLOT(..)宏進行類型轉換 //點擊按鈕關閉窗口QObject::connect(&button,SIGNAL(clicked(void)),&label,SLOT(close()));//增加退出按鈕,實現退出QObject::connect(&button3,SIGNAL(clicked(bool)),&parent,SLOT(close()));信號和槽連接的語法要求:
信號和槽連接的語法要求信號和槽參數要一致
- 可以帶有缺省參數
- 信號函數的參數可以多于槽函數,多余參數將被忽略
- 一個信號可以連接多個槽(但是執行順序不確定)
- 多個信號可以連接一個槽
- 兩個信號可以直接連接(信號級聯),應用比較少。
一個小例子
int main(int argc, char *argv[]) {QApplication app(argc,argv);QDialog parent;parent.resize(320,240);//創建水平滑塊QSlider slider(Qt::Horizontal,&parent);slider.move(20,100);slider.setRange(0,200);//創建選址框QSpinBox spin(&parent);spin.move(220,100);spin.setRange(0,200);//滑塊滑動影響選址框QObject::connect(&slider,SIGNAL(valueChanged(int)),&spin,SLOT(setValue(int)));QObject::connect(&spin,SIGNAL(valueChanged(int)),&slider,SLOT(setValue(int)));parent.show();//讓應用程序進入事件return app.exec(); }關于面向對象的Qt編程
沒啥好說的,實現一個加法計算器吧
加法計算器
- 通過面向對象的編程思想實現加法計算器
- 輸入兩個數字,按“=”按鈕顯示計算結果
- 兩個操作數必須都是合法的數字,拒絕接受任何非法字符
- 兩個操作數必須全部合法,“=”按鈕才被激活,否則禁用(不可以點擊)
- 顯示結果的控件只可查看不可修改,但支持復制到剪貼板
- 所有子窗口的大小和位置隨主窗口的縮放自動調整至最佳
寫了半個多小時,IDE卡死了,你碼沒了!!!!!!!!!!!!艸
Time::Time(QWidget *parent): QWidget(parent) {ui.setupUi(this);//初始化界面m_label = new QLabel(this);m_label->setFrameStyle(QFrame::Panel | QFrame::Sunken);m_label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//設置字體大小QFont font;font.setPointSize(20);m_label->setFont(font);//獲取系統時間按鈕m_button = new QPushButton("get time", this);m_button->setFont(font);//垂直布局器QVBoxLayout* layout = new QVBoxLayout(this);layout->addWidget(m_label);layout->addWidget(m_button);setLayout(layout);//信號和槽connect(m_button, SIGNAL(clicked()),this, SLOT(getTime())); }void Time::getTime() {qDebug() << "gettime";//獲取當前時間QTime time = QTime::currentTime();//將時間轉換為字符串形式QString str = time.toString("hh:mm:ss");//顯示時間m_label->setText(str);} class Time : public QWidget {Q_OBJECT public:Time(QWidget *parent = Q_NULLPTR);private:Ui::TimeClass ui; private:QLabel* m_label;QPushButton* m_button; public slots://獲取系統時間槽函數void getTime(void); };有缺陷,但我不想改了。
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);connect(ui->m_btnBox,SIGNAL(accepted()),this,SLOT(onAccepted()));connect(ui->m_btnBox,SIGNAL(accepted()),this,SLOT(onRejected())); }Widget::~Widget() {delete ui; } //處理OK void Widget::onAccepted(void) {if(ui->m_usernameEdit->text() == "123" &&ui->m_passwdEdit->text() == "123"){qDebug()<<"登陸成功";close();//關閉窗口}else{QMessageBox msgBox(QMessageBox::Critical,"Error","用戶名或密碼錯誤",QMessageBox::Ok,this);msgBox.exec();}}//處理取消 void Widget::onRejected(void) {QMessageBox msgBox(QMessageBox::Question,"登錄","是否確定要取消登錄",QMessageBox::Yes | QMessageBox::No,this);if(msgBox.exec() == QMessageBox::Yes){close();}}Qt的事件處理機制
什么是事件?
- 在Qt中,是以事件驅動UI工具集,包括信號和槽都依賴于Qt的事件處理機制
- 通常事件是由窗口系統或者Qt自身產生的,用以響應所發生的各類事情,比如用戶按下并釋放了鍵盤或者鼠標、窗口因縮放而需要重繪、定時器到期而應有所動作
如何處理事件?
-
在Qt中,事件被封裝成對象,所有的事件對象類型都繼承自抽象類QEvent
-
當事件發生時,首先被調用的是Q0bject類中的虛函數event(),其參數(QEvent)標識了具體的
心事件類型 -
在Qt桌面應用(Qt Widgets Application)開發中,QWidget類覆蓋了其基類中的event()虛函數,并根據具體事件調用具體事件處理函數︰
-
所有的事件處理函數都是虛函數,可以被QWidget的子類覆蓋,以提供針對不同窗口控件類型的事件處理,控件的使用者所關心的往往是定義什么樣的槽處理什么樣的信號,而控件的實現者則更關心覆蓋哪些事件處理函數
-
如果程序員希望在窗口中自定義的處理事件,可以繼承QWidget或者其子類,比如QDialog.QMainWindow,在自定義的窗口子類中重寫事件處理函數,當相應事件被觸發時,會利用多態的語法機制,所執行到的事件處理函數將是子類中重寫的版本,從而實現程序員先要的事件處理效果
案例:
定時器
定時器事件
Qt通過兩套機制為應用程序提供定時功能
- 定時器事件,由Q0bject提供
- 定時器信號,由QTimer提供>通過定時器事件實現定時器
- int Q0bject.startTimer (int interval;啟動定時器,以后每隔interval毫秒觸發一次定時器事件,返回定時器ID
- void Qobject:timerEvent (QTimerEvent* ) [virtual];//定時器事件處理函數.
- -void Qobject::killTimer(int id);//關閉參數id所標識的定時器
總結
以上是生活随笔為你收集整理的Qt学习笔记(持续更新)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关闭windows开机浏览器自动跳转MS
- 下一篇: 最佳的75个安全检测工具