2012-02-08 30 views
11

Trước tiên, tôi có danh sách QWidget mà tôi sẽ không biết độ dài cho đến khi thời gian chạy. Sau đó tôi tạo một QListWidget nơi tôi hiển thị chúng và khi ai đó nhấp vào chúng, tôi sử dụng tín hiệu currentItemChanged(QListWidgetItem*, QListWidgetItem*) để nắm bắt và nhận chỉ mục của mục được nhấp.Cách thêm danh sách QActions vào QMenu và xử lý chúng bằng một khe đơn?

Bây giờ tôi muốn thực hiện một điều tương tự trong QMenu. Tôi sẽ biết danh sách khi các QMenu và hành động của nó được xây dựng, nhưng tôi sẽ không thể mã cứng này.

Làm cách nào để tạo hành động, nắm bắt tín hiệu và kết nối chúng với cùng một vị trí có những thứ khác nhau tùy thuộc vào vị trí của hành động (chỉ mục) trong danh sách menu? Phải có một số cách để giải quyết điều này vì các ứng dụng khác sử dụng nó. Tôi đã cố gắng nhìn vào bản đồ nhưng tôi không thể tìm được cách sử dụng nó cho việc này.

Tôi đã cố gắng lấy sender trong khe nhưng không thể nhận được bất kỳ thông tin hữu ích nào từ nó.

Trả lời

15

Bạn có thể liên kết chỉ mục (hoặc bất kỳ dữ liệu nào khác) với mỗi hành động khi chúng được tạo bằng QAction::setData và kết nối tín hiệu QMenu::triggered(QAction*) với vị trí của bạn.

Sau đó, bạn sẽ có thể truy xuất dữ liệu thông qua chức năng QAction::data() của thông số vị trí của mình.

MyClass::MyClass() { 
    // menu creation 
    for(...) { 
     QAction *action = ...; 
     action->setData(10); 
     ... 
     menu->addAction(action); 
    } 
    // only one single signal connection 
    connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(mySlot(QAction*))); 
} 

void MyClass::mySlot(QAction *action) { 
    int value = action->data().toInt(); 

} 

Các phương pháp khác: lập bản đồ tín hiệu hoặc sử dụng sender(), được giải thích trong that article of Qt Quaterly.

+0

oh cảm ơn bạn! Tôi thực sự giải quyết nó theo cách tương tự bằng cách sử dụng các hành động .property và thiết lập "index" thành "i" (sử dụng for-loop). Tôi đoán dữ liệu sẽ là một cách khác để giải quyết nó :) – chikuba

+0

Tôi đã thử sử dụng cùng một giải pháp, nhưng nó không hoạt động. Bạn có thể xem http://stackoverflow.com/q/14151443/986760 và trợ giúp không. Cảm ơn? – fayyazkl

3

Cách tiếp cận chung hơn (không dành riêng cho QMenu) để tiếp cận đây là lớp học QActionGroup. Điều này cho phép bạn tách riêng các mục menu cụ thể dưới dạng nhóm liên quan hoặc nhóm các tiện ích con khác nhau lại với nhau.

void MyClass::InitMenu(QMenu* menu) 
{ 
    QActionGroup* actions1 = new QActionGroup(menu); 
    actions1->setExclusive(false); 
    actions1->addAction(menu->addAction(tr("Action1")))->setData(1); 
    actions1->addAction(menu->addAction(tr("Action2")))->setData(2); 
    actions1->addAction(menu->addAction(tr("Action3")))->setData(3); 
    actions1->addAction(menu->addAction(tr("Action4")))->setData(4); 
    actions1->addAction(menu->addAction(tr("Action5")))->setData(5); 
    connect(actions1, SIGNAL(triggered(QAction*)), SLOT(MySlot(QAction*))); 

    QActionGroup* actions2 = new QActionGroup(menu); 
    actions2->addAction(menu->addAction(tr("Undo Action1")))->setData(1); 
    actions2->addAction(menu->addAction(tr("Undo Action2")))->setData(2); 
    //... 
    connect(actions2, SIGNAL(triggered(QAction*)), SLOT(MyUndoSlot(QAction*))); 
} 

và trong khe:

void MyClass::MySlot(QAction* triggeredAction) 
{ 
    // use either the action itself... or an offset 
    int value = triggeredAction->data().toInt() 
} 
Các vấn đề liên quan