2012-04-15 29 views
70

Hãy nói rằng tôi có tín hiệu này:Sử dụng phát ra vs gọi một tín hiệu như thể đó là một chức năng thường xuyên trong Qt

signals: 
    void progressNotification(int progress); 

Tôi chỉ vừa mới biết về từ khóa Emit trong Qt. Cho đến bây giờ, tôi đã sử dụng để thực hiện các tín hiệu bằng cách chỉ gọi chúng như một hàm thông thường. Vì vậy, thay vì:

emit progressNotification(1000 * seconds); 

Tôi sẽ viết:

progressNotification(1000 * seconds); 

Gọi họ như vậy dường như để làm việc, và tất cả các khe kết nối sẽ thực hiện, vì vậy không sử dụng từ khóa Emit gây ra một hành vi khác nhau, hoặc nó chỉ là cú pháp đường?

+11

+1 Không bao giờ biết 'emit' là không cần thiết. Thật lạ lùng, rằng bạn đã học được về 'emit' lâu sau khi gọi tín hiệu trực tiếp, vì hệ thống khe cắm tín hiệu là một trong những điều đầu tiên được học về Qt. –

Trả lời

61

emit chỉ là cú pháp đường. Nếu bạn nhìn vào đầu ra được xử lý trước của hàm phát ra tín hiệu, bạn sẽ thấy emit vừa biến mất.

"ma thuật" xảy ra trong mã được tạo cho chức năng phát tín hiệu mà bạn có thể xem bằng cách kiểm tra mã C++ được tạo bởi moc.

Ví dụ một tín hiệu foo không có tham số tạo ra chức năng này thành viên:

void W::foo() 
{ 
    QMetaObject::activate(this, &staticMetaObject, 0, 0); 
} 

Và mã emit foo(); là tiền xử lý để đơn giản foo();

emit được định nghĩa trong Qt/qobjectdefs.h (trong mã nguồn mở hương vị của nguồn anyway), như sau:

#ifndef QT_NO_EMIT 
# define emit 
#endif 

(Bảo vệ xác định là cho phép bạn sử dụng Qt với các khung công tác khác có tên va chạm qua tùy chọn cấu hình QMake no_keywords.)

+11

Bạn có biết nếu có bao giờ thực hiện (hoặc một kế hoạch thực hiện) của một 'emit' mà thực sự đã làm nhiều hơn không có gì? Tôi thấy rằng có 'cú pháp cú pháp' trong trường hợp này chỉ gây nhầm lẫn cho người mới (hoặc ít nhất là tôi khi tôi là người dùng Qt mới làm quen) - có vẻ như điều gì đó kỳ diệu hoặc quan trọng đang xảy ra với từ khóa giả 'emit', khi nó không có gì cả - tất cả các phép thuật xảy ra trong một chức năng cũ thường xuyên mà 'moc' tạo ra ('moc' là phép thuật cho tín hiệu và khe cắm Qt). 'emit' là trang trí không cần thiết mà không làm gì ngoài việc có vẻ quan trọng. –

+8

Emit là _not_ "chỉ cần trang trí". 'emit' nói cho người đọc rằng ma thuật sắp xảy ra (tức là điều này sẽ kích hoạt mã trong các đối tượng lớp này có khả năng chưa bao giờ nghe đến, và các cuộc gọi này có thể đồng bộ hoặc không đồng bộ), về cơ bản là hoàn toàn bị mất nếu bạn bỏ qua từ khóa. Sử dụng nó. Đó là tự động tạo tài liệu. "Người mới" nên đọc tài liệu và hướng dẫn và 'emit' luôn ở đó (trong tài liệu chính thức). Phát hiện ra rằng bạn có thể chỉ cần gọi chức năng sẽ xảy ra sau khi bạn đã "nhìn thấy ánh sáng" - bạn không phải là một người mới nữa tại thời điểm đó. – Mat

+14

Hmm, tôi không chắc tôi đồng ý với bạn về mức độ có giá trị của 'từ khóa 'emit'. Tôi nghĩ rằng tôi đã có thể ưa thích rằng một quy ước đặt tên được sử dụng nếu có một nhu cầu để làm rõ rằng một cuộc gọi chức năng là một tín hiệu. –

-4

Tùy chọn thứ hai ngụ ý rằng bạn luôn biết tên hàm và tham số chức năng là gì và đối tượng mà bạn gửi nó đến được biết đến bởi hàm cụ thể đó. Hai trường hợp này không phải lúc nào cũng đúng, vì vậy đó là hai điều chính tại sao các khe và tín hiệu được thực hiện. "under-the-hood" cơ chế tín hiệu và khe cắm chỉ là một bảng với các con trỏ tới mọi chức năng được kết nối.

Ngoài ra, nhìn vào pdf này mà giải thích rất rõ bản chất của các tín hiệu và khe cắm cơ chế: http://www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf

+0

Cả hai cách đều cần biết tên tín hiệu và các thông số của nó - bạn đang phát ra nó, làm cách nào bạn có thể phát ra thứ gì đó mà bạn không biết? Cả hai đều có cùng ngữ nghĩa, chúng giống hệt nhau. – Mat

+0

Có thể bạn đang tạo một cuộc gọi tín hiệu với cuộc gọi trực tiếp? Nhưng tôi phải thừa nhận rằng tôi cũng tự hỏi về danh hiệu câu hỏi lúc đầu, vì tôi không bao giờ biết 'emit' chỉ là một trò chơi không có. Nhưng ngay cả trong trường hợp này đọc cơ thể câu hỏi cũng đã xóa mọi thứ, vì vậy -1. –

3

Sau 18 tháng ... Tôi bắt đầu với nhận xét trong câu trả lời của @ Mat và đã hết của phòng một cách nhanh chóng. Vì vậy, câu trả lời.

IMO emit không phải là cú pháp đường hay một từ khóa đơn giản theo nghĩa là

  1. Nó tạo mã (như được giải thích bởi @Mat ở trên),
  2. Nó giúp các cơ chế connect công nhận rằng thực sự nó là một signal
  3. Nó làm cho phần tín hiệu của bạn trở thành một hệ thống "lớn hơn", nơi tín hiệu và phản hồi (khe) có thể được thực hiện đồng bộ hoặc không đồng bộ hoặc xếp hàng, tùy thuộc vào vị trí và cách tín hiệu phát ra. Đây là một tính năng cực kỳ hữu ích của hệ thống tín hiệu/khe.

Toàn bộ hệ thống tín hiệu/khe là thành ngữ khác với lệnh gọi hàm đơn giản. Tôi tin rằng nó bắt nguồn từ mô hình quan sát viên. Ngoài ra còn có sự khác biệt chính giữa một số signalslot: tín hiệu không có để được triển khai, trong khi một vị trí phải là!

Bạn đang đi bộ xuống phố và nhìn thấy ngôi nhà đang cháy (tín hiệu). Bạn quay số 911 (kết nối tín hiệu báo cháy với khe phản hồi 911). Tín hiệu là chỉ phát ra, trong khi vị trí được triển khai bởi bộ phận cứu hỏa. Có thể không chính xác, nhưng bạn có ý tưởng. Hãy xem ví dụ về OP.

Một số đối tượng phụ trợ biết số lượng tiến trình đã được thực hiện. Vì vậy, nó có thể chỉ đơn giản là tín hiệu emit progressNotification(...). Tùy thuộc vào lớp hiển thị thanh tiến trình thực tế, để nhận tín hiệu này và thực hiện trên đó. Nhưng quan điểm kết nối với tín hiệu này như thế nào? Chào mừng bạn đến với hệ thống tín hiệu/khe của Qt. Giờ đây, người ta có thể hình dung một lớp người quản lý (thường là một loại tiện ích), bao gồm đối tượng xem và đối tượng tính toán dữ liệu (cả hai là QObjects), có thể thực hiện connect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress).

Chúng ta không đi vào các khía cạnh thiết kế của lớp người quản lý, nhưng đủ để nói rằng đây là nơi hệ thống tín hiệu/khe phát sáng. Tôi có thể tập trung vào việc thiết kế một kiến ​​trúc rất sạch sẽ cho ứng dụng của mình. Không phải luôn luôn, nhưng thường xuyên, tôi thấy rằng tôi chỉ phát ra tín hiệu nhưng thực hiện các vị trí.

Nếu chúng ta có thể sử dụng/gọi một phương thức tín hiệu mà không bao giờ phát ra nó, sau đó nó nhất thiết ngụ ý rằng bạn không bao giờ cần chức năng đó như là một tín hiệu ở nơi đầu tiên.

Các vấn đề liên quan