Qt處理批量信號的兩種方法

一,使用QSignalMapper

SignalMapper這個類可以看成是信號的翻譯和轉發器, 它可以把一個無參數的信號翻譯成帶int參數、QString參數、QObject參數或者QWidget參數的信號, 並將之轉發。 如果我有一堆的button, 可以把clicked事件放在一個函數裏處理, 只要給button編個號或者給button起個名就行了, 這樣就不用給每個button寫一個slot了

代碼解析

//mainwin.h

class MainWin : public QWidget

{
    Q_OBJECT
public:
    MainWin(QWidget *parent = 0);
private slots:
    void doClicked(const QString & btnname);//處理最終信號的槽
private:
    QSignalMapper *signalMapper;

};

 

//mainwin.cpp
MainWin::MainWin(QStringList texts, QWidget *parent) : QWidget(parent)

{

    QString buttontext = "btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn10";//10個button

    QStringList texts = buttontext.split(",");
    signalMapper = new QSignalMapper(this);
    QGridLayout *gridLayout = new QGridLayout;
    for (int i = 0; i < texts.size(); ++i)
    {
         QPushButton *button = new QPushButton(texts[i]);
         connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));//原始信號傳遞給signalmapper
         signalMapper->setMapping (button, texts[i]);
        //設置signalmapper的轉發規則, 轉發爲參數爲QString類型的信號, 並把texts[i]的內容作爲實參傳遞。
        gridLayout->addWidget(button, i / 3, i % 3);
    }

    connect(signalMapper, SIGNAL(mapped (const QString &)), this, SLOT(doClicked(const QString &)));//將轉發的信號連接到最終的槽函數
    setLayout(gridLayout);

}

 

void MainWin::doClicked(const QString& btnname)

{
    QMessageBox::information(this, "Clicked", btnname + " is clicked!");//顯示被按下的btn名稱。
}

 
*首先把原始不帶參數的信號連接到signalmapper的map槽函數, 這樣signalmapper能在第一時間接收到原始信號;

*其次調用setMapper方法告訴signalmapper怎樣去處理原始信號。 在這個例子中是把原始信號轉化爲一個帶QString參數的信號

*最後接收轉化後的帶參數信號, 這裏所把轉化後的信號與槽函數連接, 在槽函數中獲得需要的數據。

二,使用QObject *QObject::sender()

通過在槽函數中調用sender() 函數,可以獲取信號的發送對象,
通過對象名區分來處理對應的操作。

代碼解析

//mainwin.h

class MainWin : public QWidget

{
    Q_OBJECT
public:
    MainWin(QWidget *parent = 0);
private slots:
    void doClicked();//處理最終信號的槽

};

 
//mainwin.cpp
MainWin::MainWin(QStringList texts, QWidget *parent) : QWidget(parent)
{

    QString buttontext = "btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn10";//10個button

    QStringList texts = buttontext.split(",");
    QGridLayout *gridLayout = new QGridLayout;
    for (int i = 0; i < texts.size(); ++i)
    {

         QPushButton *button = new QPushButton(texts[i]);
         connect(button, SIGNAL(clicked()), this, SLOT(doClicked()));
         gridLayout->addWidget(button, i / 3, i % 3);
    }
    setLayout(gridLayout);

}

 

void MainWin::doClicked()
{
   QObject *QObj = sender();
   QPushButton *But = dynamic_cast<QPushButton *>(QObj);
   if(But)
   {
     QString  btnname  = But->objectName();
   }
    QMessageBox::information(this, "Clicked", btnname + " is clicked!");//顯示被按下的btn名稱。
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章