flash怎么做網(wǎng)站抖音流量推廣神器軟件
文章目錄
- 1、簡介
- 2、代碼實現(xiàn)
- 2.1 界面菜單“轉(zhuǎn)到槽”方法
- 2.2 界面信號槽編輯器方法
- 2.3 QT4.0的綁定方法
- 2.4 QT5.0之后的綁定方法
- 2.5 C++11的方法
- 2.6 lamda表達式方法
- 2.7 QSignalMapper方法
- 結(jié)語
1、簡介
在GUI編程中,當我們更改一個小部件時,我們通常希望通知另一個小程序。更普遍地說,我們希望任何種類的物體都能夠相互通信。例如,如果用戶單擊“關(guān)閉”按鈕,我們可能希望調(diào)用窗口的Close()函數(shù)。
其他工具包使用回調(diào)實現(xiàn)這種通信?;卣{(diào)是指向函數(shù)的指針,因此,如果您希望處理函數(shù)通知您某個事件,您可以將指向另一個函數(shù)的指針(回調(diào))傳遞給處理函數(shù)。然后,處理函數(shù)在適當?shù)臅r候調(diào)用回調(diào)。雖然使用這種方法的成功框架確實存在,但回調(diào)可能是非直觀的,并且在確?;卣{(diào)參數(shù)的類型正確性方面可能會遇到問題。
在Qt中,我們有一種替代回調(diào)技術(shù)的方法:我們使用信號和槽。當特定事件發(fā)生時,會發(fā)出一個信號。Qt的小部件有許多預定義的信號,但我們總是可以對小部件進行子類化,以向它們添加我們自己的信號。槽是響應于特定信號而調(diào)用的函數(shù)。Qt的小部件有許多預定義的插槽,但通常的做法是對小部件進行子類化,并添加自己的插槽,以便處理您感興趣的信號。
信號與槽是用于對象之間的通信的,這是 Qt 的核心。為此 Qt 引入了一些關(guān)鍵字,他們是slots、signals、emit,這些都不是 C++關(guān)鍵字,是 Qt 特有的,這些關(guān)鍵字會被 Qt 的 moc轉(zhuǎn)換為標準的 C++語句。
- 連接規(guī)則:
1、信號參數(shù)可以比槽函數(shù)多,反之則不可以
2、 一個信號可以連接多個槽
3、多個信號可以連接到一個槽
4、一個信號可以與另一個信號連接
2、代碼實現(xiàn)
2.1 界面菜單“轉(zhuǎn)到槽”方法
使用這種方法我們不需要使用connect函數(shù)將信號與槽函數(shù)做連接。 這里槽函數(shù)的命名有一定的規(guī)則,一般是 on_objectname_signal 這樣來命名的。
不需要使用 connect 函數(shù),可以通過Qt Creator 界面來完成發(fā)送信號和槽函數(shù)的連接。在按鈕上鼠標右鍵彈出菜單,選擇“轉(zhuǎn)到槽…”,如下:
彈出小窗口,選擇“clicked()”后確定。
然后在文件里自動生成代碼如下:
- mainwindow.h
private slots:void on_pushButton_clicked();
- mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{QMessageBox::information(this, "", "on_pushButton_clicked");
}
我們也可以完全在代碼里實現(xiàn)這種方式:
- mainwindow.h
private slots:void on_myButton_clicked();
- mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QPushButton *button = new QPushButton(this); // 創(chuàng)建按鈕button->setObjectName("myButton"); // 指定按鈕的對象名ui->setupUi(this); // 要在定義了部件以后再調(diào)用這個函數(shù)
}
void Widget::on_myButton_clicked() // 使用自動關(guān)聯(lián)
{close();
}
2.2 界面信號槽編輯器方法
打開信號槽編輯界面,添加記錄,設(shè)置相關(guān)參數(shù)。
在mainwindow.ui界面定義文件中會自動生成對應的代碼,可以手動修改。
2.3 QT4.0的綁定方法
Qt4使用了SIGNAL和SLOT這兩個宏,將信號和槽的函數(shù)名轉(zhuǎn)換成了字符串。使用字符串導致了Qt4有以下缺點:一旦出現(xiàn)連接不成功的情況,Qt 4 是沒有編譯錯誤的
connect(obj1, SIGNAL(fun1(param1, param2,...)), obj2, SLOT(fun2(param1,...)));
優(yōu)點:對所有控件都適用。
缺點:書寫繁瑣,槽函數(shù)必須在slots標簽下。
(1)和控件有關(guān)系的信號槽
- mainwindow.h
private slots:void pushButon1_clicked();void onTextEdited(QString);
- mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(pushButon1_clicked()));connect(ui->lineEdit, SIGNAL(textEdited(QString)), this, SLOT(onTextEdited(QString)));
}void MainWindow::pushButon1_clicked()
{QMessageBox::information(this, "", "pushButon1_clicked");
}void MainWindow::onTextEdited(QString s)
{qDebug() << s;
}
(2)和控件無關(guān)系的信號槽
- mainwindow.h
signals: //信號:void mySignal_1(int a);void mySignal_2(int a, float b);private slots: //槽:void mySlot_1(int b);void mySlot_2(int b);
- mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//信號槽:connect(this,SIGNAL(mySignal_1(int)),this,SLOT(mySlot_1(int)));connect(this, SIGNAL(mySignal_2(int, float)), this, SLOT(mySlot_2(int)));
}
void MainWindow::mySlot_1(int b)
{QString str = QString::number(b);QMessageBox::information(this, "1", str);
}
void MainWindow::mySlot_2(int b)
{QString str = QString::number(b);QMessageBox::information(this, "2", str);
}
void MainWindow::test()
{//發(fā)送信號:emit mySignal_2(5, 2.2);emit mySignal_1(123);
}
注意:在不進行參數(shù)傳遞時,信號槽綁定時也是要求信號的參數(shù)數(shù)量大于等于槽函數(shù)的參數(shù)數(shù)量。這種情況一般是一個帶參數(shù)的信號去綁定一個無參數(shù)的槽函數(shù)。
2.4 QT5.0之后的綁定方法
Qt 5 推出了新的 connect 函數(shù),不需要使用 SIGNAL() 和 SLOT() 宏,可以在編譯時做類型檢查。
- mainwindow.h
public:void textChanged(QString);void pushButon1_clicked();
- mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->pushButton,&QPushButton::clicked,this,&::MainWindow::pushButon1_clicked);connect(ui->lineEdit, &QLineEdit::textEdited, this, &MainWindow::textChanged);void(MainWindow:: *buttonClickSlot)() = &MainWindow::pushButon1_clicked;void(MainWindow:: *textEditedSlot)(QString) = &MainWindow::textChanged;connect(ui->pushButton, &QPushButton::clicked, this, buttonClickSlot);connect(ui->lineEdit, &QLineEdit::textEdited, this, textEditedSlot);
}void MainWindow::pushButon1_clicked()
{QMessageBox::information(this, "", "pushButon1_clicked");
}
void MainWindow::textChanged(QString s)
{qDebug() << s;
}
connect()函數(shù)基于函數(shù)指針的重載形式:
[static] QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal,
const QObject *receiver,
PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection)
注意:這是QT5中加入的一種重載形式,指定信號和槽兩個參數(shù)不再使用SIGNAL()和 SLOT()宏,并且槽函數(shù)不再必須是使用slots關(guān)鍵字聲明的函數(shù),可以是任意能和信號關(guān)聯(lián)的成員函數(shù)。要使一個成員函數(shù)可以和信號關(guān)聯(lián),那么這個函數(shù)的參數(shù)數(shù)目不能超過信號的參數(shù)數(shù)目,但是并不要求該函數(shù)擁有的參數(shù)類型和信號中對應的參數(shù)類型完全一致,只需要可以進行隱式轉(zhuǎn)換即可。
connect(dlg, &myWindwow::test1, this, &myWidget::test2);
2.5 C++11的方法
- mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->pushButton, QOverload<bool>::of(&QPushButton::clicked),this,&::MainWindow::pushButon1_clicked);
}void MainWindow::pushButon1_clicked()
{QMessageBox::information(this, "", "pushButon1_clicked");
}
2.6 lamda表達式方法
還支持C++11 中的lambda表達式,可以在關(guān)聯(lián)時直接編寫信號發(fā)射后要執(zhí)行的代碼。使用 Lambda表達式的好處是代碼的書寫更加方便快捷。在connect 函數(shù)中,槽函數(shù)參數(shù)我們可以改用Lambda表達式的方式來進行傳參。
使用Lambda表達式,我們就不需要在類中對槽函數(shù)做任何的聲明了。Lambda表達式是C++ 11的內(nèi)容,在比較低的 Qt版本中,要注意在Pro項目文件中加入 CONFIG += C++ 11。
connect(dlg, &MyWindow::test1, [ = ](int value){ui->label->setText(tr("獲取的值是:%1"),arg(value));
});
- mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->pushButton, QOverload<bool>::of(&QPushButton::clicked),[=](){QMessageBox::information(this, "", "lamda表達式綁定成功!");});connect(ui->pushButton, &QPushButton::clicked, this, [=](){this->close();});connect(ui->lineEdit, &QLineEdit::textEdited, this, [=](QString s){qDebug() << s;});
}
或
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->pushButton, &QPushButton::clicked, this, [=](){QMessageBox::information(this, "", "lamda表達式綁定成功2!");});
}
2.7 QSignalMapper方法
QSignalMapper類收集了一系列的無參信號,然后使用相對于信號發(fā)送者來說的整數(shù)、字符串或控件參數(shù)來重新發(fā)送它們。
QSignalMapper類支持使用setMapping()函數(shù)將一個特定的整數(shù)或字符串和一個特定的對象關(guān)聯(lián)起來。
可以將對象的信號(比如button的clicked)連接到QSignalMapper對象的map()槽函數(shù)上,而map()槽函數(shù)又會使用與對象相關(guān)聯(lián)的整數(shù)或字符串來發(fā)送mapped()信號。
QSignalMapper類可以看成是信號的翻譯和轉(zhuǎn)發(fā)器。
它可以把一個無參的信號翻譯成帶int參數(shù)、QString參數(shù)、 QObject* 參數(shù)或者QWidget *參數(shù)的信號,并將之轉(zhuǎn)發(fā)。
QSignalMapper類的功能核心是要建立一個從原始信號的object到需要的數(shù)據(jù)的映射(setMapper函數(shù))。 map()作為QSignalMapper的一個槽函數(shù),將根據(jù)setMapping規(guī)則轉(zhuǎn)發(fā)mapped()信號。
QSignalMapper可將多個有類似處理方式signal用一個slot實現(xiàn),相當于將N個一對一映射通過集中轉(zhuǎn)換成多對一映射。
- mainwindow.h
#include <QSignalMapper>private:
Ui::MainWindow *ui;
QSignalMapper * myMapper;private slots:void showLabel(int i);
- mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);myMapper = new QSignalMapper();//新建一個按鈕數(shù)組,id為push[i]QPushButton * push[5];for (int i = 0; i < 5; i++){push[i] = new QPushButton(this);push[i]->setGeometry(300, 60 + 30 * i, 90, 24);push[i]->setText(QString("button%1").arg(i));connect(push[i], SIGNAL(clicked()), myMapper, SLOT(map()));myMapper->setMapping(push[i], i);}connect(myMapper, SIGNAL(mapped(int)), this, SLOT(showLabel(int)));
}void MainWindow::showLabel(int i)
{ui->label->setText(QString("button%1 is clicked").arg(i));
}
結(jié)語
如果您覺得該方法或代碼有一點點用處,可以給作者點個贊,或打賞杯咖啡;
╮( ̄▽ ̄)╭
如果您感覺方法或代碼不咋地
//(ㄒoㄒ)//,就在評論處留言,作者繼續(xù)改進;
o_O???
如果您需要相關(guān)功能的代碼定制化開發(fā),可以留言私信作者;
(????)
感謝各位童鞋們的支持!
( ′ ▽′ )ノ ( ′ ▽′)っ!!!