QSignalMapper類處理多訊號關聯同一個槽的方法(1)

來源:互聯網
上載者:User

標籤:

QSignalMapper這個類並不是個新鮮概念, 早在Qt2裡就已經存在, 而且它的功能也是始終如一。 不過由於宣傳力度不夠(例子裡涉及到它的很少)瞭解這個類人可能還不是很多, 所以特此撰文介紹此類的功能和用法。簡單的理解,可以把SignalMapper這個類看成是訊號的翻譯和轉寄站, 它可以把一個無參數的訊號翻譯成帶int參數、QString參數、QObject*參數或者QWidget*參數的訊號, 並將之轉寄。這麼一說大家有沒有聯想到該類的適用範圍呢? 呵呵, 是不是一下就想到了如果我有一堆的button, 可以把clicked事件放在一個函數裡處理, 只要給button編個號或者給button起個名就行了, 這樣就不用給每個button寫一個slot了,豈不是很方便? 

        下面這段代碼就實現了該功能:

/***mainwin.h***/

#ifndef MAINWIN_H#define MAINWIN_H#include <QWidget>class QSignalMapper;class MainWin : public QWidget{    Q_OBJECT    public:    MainWin(QWidget *parent = 0);    ~MainWin();private slots:    void doClicked(const QString &btnname);private:    QSignalMapper *signalMapper;};#endif // MAINWIN_H

/***mainwin.cpp***/

#include "mainwin.h"#include <QSignalMapper>#include <QLayout>#include <QPushButton>#include <QMessageBox>MainWin::MainWin(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!");}MainWin::~MainWin(){    }

/***main.cpp***/

#include <QApplication>#include "mainwin.h"int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWin w;    w.show();        return a.exec();}

從這個例子來看QSignalMapper的用法是非常簡單的, 也很容易理解。

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

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

(3)最後接收轉化後的帶參數訊號, 這裡所把轉化後的訊號與槽函數串連, 在槽函數中獲得需要的資料。

QSignalMapper類的功能核心是要建立一個從發出原始訊號的object到需要的資料的映射(setMapper函數), 如果你的程式恰巧需要這樣的功能,那麼當然QSignalMapper就是當仁不讓的最佳選擇。 除了上述最常見的用法, 我們也來開動腦筋想想還有什麼別的場合適合使用這個類呢?

在Qt的examples裡有一個例子用到了QSignalMapper這個類, 在examples/mainwindow/mdi/mainwindow.cpp裡。 它的用法是將QWidget指標作為參數, 然後菜單選中的訊號映射到子Window的指標, 最終由QMainWindow來處理, 用於實現子視窗的切換。 這個用法很有些意思, 可以說是QSignalMapper的最佳用例, 建議大家學習一下。 這裡截取其中最核心的代碼, 有注釋應該很好看懂吧, 如果還是有問題就留言:

//主類從QMainWindow派生MainWindow::MainWindow(){    //...    windowMapper = new QSignalMapper(this);    connect(windowMapper, SIGNAL(mapped (QWidget *)), this, SLOT(setActiveSubWindow(QWidget *)));    //轉寄的訊號直接連接到QMainWindow的setActiveSubWindow槽    //...}void MainWindow::updateWindowMenu(){     //... QList windows = mdiArea->subWindowList();    separatorAct->setVisible(!windows.isEmpty());    for (int i = 0; i < windows.size(); ++i)    {        MdiChild *child = qobject_cast(windows.at(i)->widget());        QString text;        if (i < 9)        {            text = tr("&%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile());        }        else        {            text = tr("%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile());        }        QAction *action = windowMenu->addAction(text);        action->setCheckable(true);        action ->setChecked(child == activeMdiChild());        connect(action, SIGNAL(triggered()), windowMapper, SLOT(map ()));//監控action的triggered訊號                             windowMapper->setMapping (action, windows.at(i));//建立action指標到QWidget*的映射 }          //...    }}<pre name="code" class="cpp">void MainWindow::setActiveSubWindow(QWidget *window) // 設定活動子視窗{    if (!window) // 如果傳遞了視窗組件,則將其設定為使用中視窗        return;    ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));}

此外,在C:\Qt\4.8.4\examples\tools\inputpanel此例中也用到了訊號映射器。

 

引自:http://blog.csdn.net/cuteqt/article/details/4306900

轉自:http://blog.csdn.net/zzwdkxx/article/details/28437441

QSignalMapper類處理多訊號關聯同一個槽的方法(1)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.