2009-06-02 34 views
27

Tôi có một menu thanh tác vụ khi được nhấp được kết nối với một vị trí nhận được sự kiện kích hoạt. Bây giờ vấn đề là tôi muốn biết mục menu nào được nhấp, nhưng tôi không biết cách gửi thông tin đó đến hàm được kết nối tới. Đây là thông tin được sử dụng để kết nối hành động với hàm:PyQt gửi tham số đến vị trí khi kết nối với tín hiệu

QtCore.QObject.connect(menuAction, 'triggered()', menuClickedFunc) 

Tôi biết rằng một số sự kiện trả về giá trị, nhưng được kích hoạt() thì không. Vì vậy, làm thế nào để tôi thực hiện điều này xảy ra? Tôi có phải tạo ra tín hiệu của riêng mình không?

Trả lời

40

Sử dụng một lambda

Dưới đây là một ví dụ từ PyQt book:

self.connect(button3, SIGNAL("clicked()"), 
    lambda who="Three": self.anyButton(who)) 

Bằng cách này, bạn cũng có thể sử dụng functools.partial, nhưng tôi tìm ra phương pháp lambda đơn giản và rõ ràng hơn.

+0

Xin chào, cảm ơn rất nhiều! Hoàn toàn cứu tôi rất nhiều thất vọng. Tôi có lẽ nên giữ một cuốn sách đó ... – johannix

+1

Bạn thực sự cần - đó là một cuốn sách rất hay. –

+0

câu trả lời tuyệt vời, đây là chính xác những gì tôi đang tìm kiếm – Bedros

0

Nói chung, bạn nên có từng mục menu được kết nối với một vị trí khác nhau và mỗi vị trí chỉ xử lý chức năng cho mục menu của riêng nó. Ví dụ: nếu bạn có các mục menu như "lưu", "đóng", "mở", bạn nên tạo một vị trí riêng biệt cho từng mục, không cố gắng có một vị trí duy nhất có tuyên bố trường hợp trong đó.

Nếu bạn không muốn thực hiện theo cách đó, bạn có thể sử dụng chức năng QObject::sender() để nhận con trỏ tới người gửi (ví dụ: đối tượng phát ra tín hiệu). Tôi muốn nghe thêm một chút về những gì bạn đang cố gắng để thực hiện, mặc dù.

+3

OP hỏi về một nhu cầu hoàn toàn hợp pháp. Đôi khi nhiều mục menu được tạo tự động (hoặc chỉ rất giống) và nên tham chiếu đến cùng một vị trí. Có một cách tiêu chuẩn để đạt được điều này trong PyQt được đề nghị trong cuốn sách và trong hướng dẫn. –

7

Như đã đề cập here bạn có thể sử dụng hàm lambda để chuyển các đối số thừa vào phương thức bạn muốn thực hiện.

Trong ví dụ này, bạn có thể chuyển một chuỗi obj vào hàm AddControl() được gọi khi nút được nhấn.

# Create the build button with its caption 
self.build_button = QPushButton('&Build Greeting', self) 
# Connect the button's clicked signal to AddControl 
self.build_button.clicked.connect(lambda: self.AddControl('fooData')) 
def AddControl(self, name): 
    print name 

Nguồn: snip2code - Using Lambda Function To Pass Extra Argument in PyQt4

3

sử dụng functools.partial

nếu không bạn sẽ tìm thấy bạn không thể vượt qua đối số tự động khi kịch bản đang chạy, nếu bạn sử dụng lambda.

+2

Chăm sóc để sao lưu điều này bằng một số bằng chứng? – ekhumoro

+0

Bạn có thể vượt qua các đối số một cách linh hoạt vào một lambda được tạo ra, như lambdas (như các hàm 'def''ed bình thường) là các bao đóng và do đó nắm bắt các ràng buộc từ phạm vi kèm theo của chúng. (Có, điều đó cũng ngụ ý rằng như là một lựa chọn thứ ba bạn có thể sử dụng một hàm 'def''ed 'and_ địa phương tự động truyền tham số cho nó.) Ngoài ra, đừng quên rằng bạn có thể sử dụng các đối số mặc định để truyền các giá trị động tới _both_ của chúng . Tuy nhiên, có nói rằng, cá nhân tôi thích 'functools.một phần' là tốt, lý do của riêng tôi là nó "cảm thấy" nhẹ hơn một 'lambda' (mà không làm cho một tuyên bố rằng nó thực sự là). – blubberdiblub

0

Tôi cũng muốn thêm rằng bạn có thể sử dụng phương thức sender nếu bạn chỉ cần tìm hiểu tiện ích nào đã gửi tín hiệu. Ví dụ:

def menuClickedFunc(self): 
    # The sender object: 
    sender = self.sender() 
    # The sender object's name: 
    senderName = sender.objectName() 
    print senderName 
Các vấn đề liên quan