带参的信号、lamda表达式及坐标系统
帶參的信號、lamda表達式及坐標系統(tǒng)
文章目錄
- 帶參的信號、lamda表達式及坐標系統(tǒng)
- 一、帶參的信號
- 二、lamda表達式
- 三、坐標系統(tǒng)
一、帶參的信號
1. 自定義信號(這個信號不像標準信號是一個宏,而是一個自定義信號函數(shù),注意是信號函數(shù)不是信號處理函數(shù),信號處理函數(shù)是槽函數(shù))
- 信號必須由signals關鍵字聲明
- 信號沒有返回值但是可以有參數(shù)
- 信號就是函數(shù)的聲明無需實現(xiàn)
- 使用的時候需要加emit + 信號函數(shù)的方式
- 信號可以重載
2. Qt5重載帶參信號的使用
**我們上面說過,自定義信號就是自定義一個信號函數(shù),只有聲明沒有實現(xiàn)**,所以也可以按照函數(shù)指針的方式進行區(qū)分,不過和函數(shù)指針的區(qū)別是它要加上信號所在類名::信號函數(shù)那么看下面這種情況:
signals:void Mysignal();void Mysignal(int,QString);void dealsub();void dealsold(int,QString); connect(&w,&SubWidget::Mysignal,this,&MainWidget::dealsub);connect(&w,&SubWidget::Mysignal,this,&MainWidget::dealsold);void MainWidget::dealsold(int num,QString arg){qDebug()<<num<<" "<<arg.toUtf8().data();}void MainWidget::dealsub(){w.hide();this->show();}我們重載了Mysignal()信號,在進行connect關聯(lián)槽函數(shù)時編譯就會出錯,因為編譯器無法區(qū)分SubWidget::Mysignal信號是帶參數(shù)的還是不帶參數(shù)的,所以應進行區(qū)分。
方法:所在類名::信號函數(shù)一起構成函數(shù)指針
void (SubWidget::*sub)() = &SubWidget::Mysignal; connect(&w,sub,this,&MainWidget::dealsub);void (SubWidget::*subsignal)(int,QString) = &SubWidget::Mysignal; connect(&w,subsignal,this,&MainWidget::dealsold);3.QT中的輸出
qDebug:函數(shù)
- 注意第一個q是小寫
- 注意還有一個()
- 自動換行
- 和cout用法基本一樣
4. QString轉char*
//字節(jié)數(shù)組 QByteArray QString::toUtf8() const //C字符串 char *QByteArray::data()例:
//arg.toUtf8() -> 字節(jié)數(shù)組 //arg.toUtf8().data()->C字符串 qDebug()<<num<<" "<<arg.toUtf8().data();5. Qt4信號連接
- Qt4槽函數(shù)必須有slots聲明
- SIGNAL和SLOT宏 是將函數(shù)名字轉換為字符串
- 采用Qt5的函數(shù)指針的方式使用會參與類型安全檢查,而Qt4宏的方式不參與安全檢查,只有到運行時才報錯
使用Qt4宏的方式也可以實現(xiàn)區(qū)分重載信號,方便使用,但是一定要注意Qt4宏的方式的缺陷,所以一般采用Qt5的方式,雖然麻煩但是安全
二、lamda表達式
C++11新增加加了lamda表達式,所以也可以用lamda表達式配合Qt信號一起使用!
使用的方式:在項目文件(.pro)中加入CONFIG += c++11
QPushButton* b4 = new QPushButton(this);b4->setText("i am lambda");b4->move(1,200); //this可寫可不寫 connect(b4,&QPushButton::clicked,[](bool check){qDebug()<<"i am lambda";qDebug()<<check;});- 注意lambda的捕獲列表既可以以值方式捕獲,也可以以引用的方式進行捕獲,但是 在信號這里最好用值的方式進行捕獲
假設上面的代碼以引用的方式捕獲b4,然后在函數(shù)體內對b4進行修改
QPushButton* b4 = new QPushButton(this);b4->setText("i am lambda");b4->move(1,200); //this可寫可不寫 connect(b4,&QPushButton::clicked,[&b4](bool check){qDebug()<<"i am lambda";qDebug()<<check;b4->move(2,200);});程序就會 出錯,因為connect正在使用b4,而函數(shù)體內的b4剛好是引用方式捕獲的,也就是一個別名,內部正在修改,兩者就會矛盾,就會導致程序崩潰!
- 注意信號的發(fā)出者:
上面這個代碼的功能是當按下b1按鈕時,主窗口關閉,你們可能認為信號是b1按鈕發(fā)送的,其實不是,信號是信號擁有者發(fā)送的,而當按下b1按鈕時只是觸發(fā)了槽函數(shù),由槽函數(shù)來進行發(fā)送信號
三、坐標系統(tǒng)
1. move函數(shù)
移動按鈕是使用move函數(shù),而移動窗口也是使用move函數(shù),因為move函數(shù)是繼承與QWidgets,而QWidgets基本上是所有控件的基類,所以窗口也可以用move移動
2.坐標系統(tǒng)
- 對于主窗口來說:坐標系統(tǒng)是相對于屏幕而言,移動的起點是相對于屏幕的左上角, x:往右遞增,y往下增長
- 對于子窗口來說:坐標系統(tǒng)就是相對于主窗口而言的,移動的起點是主窗口的空白區(qū)域,不包括邊框
總結
以上是生活随笔為你收集整理的带参的信号、lamda表达式及坐标系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两个独立的窗口和自定义信号
- 下一篇: java信息管理系统总结_java实现科