2012-03-25 9 views
12

Để kết nối tín hiệu với các khe, theo như tôi biết, các thông số của tín hiệu cần phải khớp với các thông số của khe. Ví dụ:Kết nối tín hiệu với các khe với giá trị không đổi

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(closeDockWidget())); 

Nhưng nếu tôi muốn có tín hiệu gọi là vị trí có số lượng thông số khác nhau nhưng luôn chuyển giá trị không đổi vào vị trí. Ví dụ: sử dụng đoạn mã trên:

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(setDockWidget(false))); 

Hoặc nói cách khác, bất cứ khi nào nút được nhấn, hàm này gọi hàm sai là tham số sai. Điều này có thể không?

Trả lời

8

Không, không thể thực hiện được. Bạn chỉ được phép kết nối các khe với số lượng đối số ít hơn hoặc bằng nhau, so với tín hiệu tương ứng. (xem documentation)

Bạn phải tạo thời điểm proxy, cuộc gọi đó sẽ gọi đến vị trí mong muốn.

+1

Câu trả lời này không còn thực sự hợp lệ, vì cú pháp Qt5 trên C++ 11 làm cho nó khá dễ sử dụng một lambda cho mục đích này. –

+1

@ André, Ở phía bên kia, bạn chỉ có thể 'tạo ra khe proxy, mà sẽ gọi mong muốn một.' bây giờ tại chỗ – Lol4t0

+1

Chắc chắn, bạn có thể. Nhưng một khe phụ có nghĩa là nhiều thứ hơn trong tiêu đề bạn không muốn, phơi bày với các cuộc gọi bên ngoài (vâng, ngay cả khi một khe riêng có thể được gọi từ bên ngoài) và lan rộng xung quanh mã của bạn trên nhiều vị trí. Bạn thậm chí có thể cần thêm các biến thành viên để chứa các giá trị bạn muốn chuyển, do đó giới thiệu trạng thái bổ sung trong lớp của bạn. Giải pháp lambda thanh lịch hơn nhiều đến nỗi nó loại bỏ sự ra đời của một khe proxy như một giải pháp IMO. –

6

Nói cách khác, có, bạn có thể. Nhưng nó không phải là rất mạnh mẽ: chỉ cần khai báo setDockWidget theo cách này:

[virtual] void setDockWidget(bool state=false) ; 

Và tuyên bố các kết nối theo cách này:

connect(emitter, SIGNAL(closeButtonClicked()), receiver, SLOT(setDockWidget())); 

setDockWidget gọi là không có đối số đi những mặc định.

8

Bạn có thể sử dụng lambda với muốn gọi với đối số không đổi. Ví dụ:

connect(obj, &ObjType::signalName, [this]() { desiredCall(constantArgument); }); 

Tìm hiểu thêm về cú pháp kết nối mới: https://wiki.qt.io/New_Signal_Slot_Syntax.

+0

Trong trường hợp của bạn là nó có thể kết hợp đối số liên tục với biến? –

+0

@AlekseyKontsevich: Nếu tôi hiểu bạn một cách chính xác, bạn cũng muốn chuyển một biến từ tín hiệu sang khe đó? Chắc chắn bạn có thể. Làm cho nó trở thành một đối số cho lambda và sử dụng đối số đó trong lời gọi hàm. Tuy nhiên, tôi khuyên bạn nên sử dụng đối số ngữ cảnh với giá trị 'this'. Bằng cách này, bạn có thể chắc chắn rằng kết nối bị hủy nếu đối tượng tiếp nhận bị hủy. Nếu không, bạn có thể kết thúc trong hành vi không xác định. –