2011-02-07 32 views
11

Tôi đang thực hiện một chương trình nhắn tin trò chuyện nhỏ, cần một danh sách các kênh trò chuyện mà người dùng đã tham gia. Để đại diện cho danh sách này bằng đồ thị, tôi đã tạo danh sách QPushButtons, tất cả đều đại diện cho một kênh khác. Các nút này được thực hiện với các phương pháp sau đây, và đó là nơi vấn đề của tôi đá trong: (. ActivePanelContents là một QWidget chứa danh sách)Làm thế nào để chuyển các biến vào các phương thức khe trong QT?

void Messenger::addToActivePanels(std::string& channel) 
{ 
    activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents")); 
    pushButton = new QPushButton(activePanelsContents); 
    pushButton->setObjectName("pushButton"); 
    pushButton->setGeometry(QRect(0, 0, 60, 60)); 
    pushButton->setText(""); 
    pushButton->setToolTip(QString(channel.c_str())); 
    pushButton->setCheckable(true); 
    pushButton->setChecked(false); 
    connect(pushButton, SIGNAL(clicked()), this, SLOT(switchTab(channel))); 
} 

Vấn đề là mỗi nút nên gọi phương thức switchTab(string& tabname) khi được nhấp, bao gồm tên của kênh cụ thể dưới dạng biến. Việc triển khai này không hoạt động và tôi chưa thể tìm hiểu cách thực hiện đúng cách này.

Trả lời

0

Bạn có thể thử có khe switchTab không tham số và sử dụng QObject::sender để nhận đối tượng đã gửi tín hiệu.

Messenger::switchTab() 
{ 
    QObject* sender = this->sender(); 
    QPushButton* button = qobject_cast<QPushButton*>(sender); 
    if(button) 
    { 
    // Do stuff... 
    } 
} 
+0

Hãy nhận biết của những lời cảnh báo trước khi sử dụng QObject :: người gửi trong mã của bạn –

+0

Không chắc chắn lý do tại sao bài đăng của bạn được sử dụng hết, nhưng dù sao cũng được. Bạn đã giúp rất nhiều – parsecer

1

Không sử dụng phương thức người gửi trừ khi bạn hoàn toàn phải làm vậy. Nó liên kết trực tiếp với hàm chỉ được sử dụng như một khe (không thể gọi trực tiếp). Giữ lại các hành vi của việc có chức năng chấp nhận một chuỗi và chỉ cần thực hiện một cơ chế mà bạn có thể gọi nó.

Một phương pháp, trong số những phương pháp khác bạn có thể tìm thấy, là tận dụng việc sử dụng QSignalMapper. Nó sẽ ánh xạ đối tượng đến các giá trị và tạo lại các tín hiệu của chữ ký thích hợp.

1

tôi sẽ làm điều đó với "chuyển tiếp" đối tượng:

Tạo TabSwitchRelay mà là một sub-class của QObject với constructor này:

TabSwitchRelay::TabSwitchRelay(QObject *parent, Messanger * m, const QString & c) 
: QObject(parent), m_messanger(m), m_channel(c) 
{ 
} 

Nó cũng có một khe cắm clicked():

void TabSwitchRelay::clicked() 
{ 
    m_messager->switchTab(m_channel); 
} 

Bây giờ hãy thay thế dòng trong mã của bạn kết nối với điều này:

TabSwitchRelay * tabRelay = new TabSwitchRelay(pushButton, this, channel); 
connect(pushButton, SIGNAL(clicked()), tabRelay, SLOT(clicked())); 

Nó không được thử nghiệm nhưng bạn nhận được ý tưởng cơ bản.

7

Đối với chuỗi và số nguyên, bạn có thể sử dụng QSignalMapper. Trong lớp Messenger của bạn, bạn sẽ thêm một đối tượng QSignalMapper mapper, và chức năng của bạn sẽ trông như thế:

void Messenger::addToActivePanels(std::string& channel) 
{ 
    activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents")); 
    pushButton = new QPushButton(activePanelsContents); 
    // ... 
    connect(pushButton, SIGNAL(clicked()), &mapper, SLOT(map())); 
    mapper.setMapping(pushButton, QString(channel.c_str())); 
} 

và sau khi bạn đã thêm tất cả các kênh để tấm hoạt động của bạn, bạn gọi

connect(&mapper, SIGNAL(mapped(const QString &)), this, SLOT(switchTab(const QString &))); 
+0

Điều này dường như không hoạt động ... switchTab() chỉ đơn giản là không bao giờ được gọi là, mặc dù không có lỗi được đưa ra bất cứ nơi nào cả. – Neko

+0

Liệu 'switchTab()' có một 'const QString &'? Nếu không, bạn cần phải thay đổi nó. Qt không cho phép bạn vượt qua 'std :: string' (hoặc, nói chung, bất kỳ loại nào không được đăng ký với' qRegisterMetaType') thông qua các tín hiệu và các khe. Lỗi bên trong 'SIGNAL' và' SLOT' không được phát hiện cho đến khi thời gian chạy, vì các macro đó chuyển đối số của chúng thành chuỗi. Rất có thể Qt đang in một thông báo lỗi đến bàn điều khiển khi nó cố gắng tạo kết nối tới 'switchTab (const QString &)'. –

3

Sử dụng QSignalMapper để vượt qua các biến;

 QSignalMapper* signalMapper = new QSignalMapper (this) ; 
     QPushButton *button = new QPushButton(); 


     signalMapper -> setMapping (button, <data>) ; 
     connect (signalMapper, SIGNAL(mapped(QString)), this, 
        SLOT(buttonClicked(QString))) ; 

trong vùng i.e

void class::buttonClicked(QString data){ 

    //use data 
    // to get sender 
    QSignalMapper *temp = (QSignalMapper *)this->sender(); 
    QPushButton *btn = (QPushButton *)temp->mapping(data); 
    // use btn 

} 

Hy vọng ans của tôi có thể giúp bạn

+0

Cảm ơn câu trả lời này. Tôi đã sử dụng QSignalMapper với QTNetworkRequest và không biết tôi đã phải sử dụng Mapper-> ánh xạ (dữ liệu) để có được các đối tượng trong trường hợp như vậy. Tôi chỉ đơn giản là sử dụng qobject_cast (người gửi) mà chỉ hoạt động khi bạn không có tham số. – fayyazkl

0

nếu bạn đang sử dụng Qt5, bạn có thể làm điều đó thông qua lambda:

connect(sender, &Sender::valueChanged, [=](){ myMethod(5); }); 

void myMethod(int value) 
{ 
    // do stuff 
} 
Các vấn đề liên quan