2009-05-10 33 views
11

Tôi khá mới lập trình với Qt và có câu hỏi. Phiên bản ngắn:Tín hiệu Qt & câu hỏi thừa kế

Làm cách nào để kế thừa các tín hiệu được xác định trong các siêu lớp?

Tôi cố gắng để phân lớp của người khác QTWidgets độc đáo làm thay đổi một số hành vi mặc định:

 

//Plot3D is a QWidget that defines a signal "rotationChanged" 
class matLinePlot : public QObject, public Plot3D { 

    Q_OBJECT; 
     //etc... 
public: 
     //etc... 

     //Catch Plot3D's signal "rotationChanged" and do some magic with it: 
    void initPlot(){ 
       QObject::connect(this, SIGNAL(rotationChanged(double , double , double)), 
      this, SLOT(myRotationChanged(double, double, double))); 
    } 
}; 

Vấn đề là trong QObject :: dòng connect. Những gì tôi muốn làm là kết nối các SIGNAL rotationChanged (từ qwt3D_plot.h) đến một chức năng địa phương/SLOT - "myRotationChanged". Tuy nhiên, bất cứ khi nào tôi làm điều này, tại thời điểm chạy, tôi nhận được:

Object::connect: No such signal matLinePlot::rotationChanged(double, double, double)

trong C: ... \ matrixVisualization.h. Tất nhiên, tôi biết rằng rotationChanged không có trong matrixVisualization.h - đó là trong qwt_plot3D.h, nhưng tôi nghĩ rằng kể từ khi tôi kế thừa từ Plot3D mọi thứ sẽ ổn. Nhưng, bây giờ tôi nghĩ về nó, vì SIGNAL và SLOT là các macro, tôi giả định MOC không biết/quan tâm đến việc thừa kế.

Điều này dẫn tôi đến câu hỏi của tôi - vì MOC và SIGNALS/SLOTS dường như không biết về thừa kế vv: làm cách nào để phân lớp một tiện ích được xác định ở nơi khác và truy cập vào tín hiệu của tiện ích?

Tôi có rất nhiều ví dụ về cách sử dụng đóng gói để thực hiện một cái gì đó như thế này, nhưng tôi sợ tôi không hiểu làm thế nào để làm điều này với thừa kế.

Xin lỗi nếu đây là một câu hỏi vô lý - tôi cảm thấy như tôi đang thiếu điều gì đó hiển nhiên.

+1

tham chiếu bạn nhìn thấy trong lỗi "matrixVisualization.h" hiển thị trong tệp nào kết nối QObject :: không thành công, không phải nơi cố gắng "tìm" cho tín hiệu phù hợp. –

Trả lời

9

Tôi đoán vấn đề là đa kế thừa:

class matLinePlot : public QObject, public Plot3D 
... 

tôi cho rằng Plot3D là một lớp con của QObject? Trong trường hợp này, bạn nên làm

class matLinePlot : public Plot3D 
... 

để thay thế.

+1

Điều đó làm cho mọi thứ vào một lỗi liên kết: 1> moc_matrixVisualization.obj: lỗi LNK2001: chưa được giải quyết biểu tượng bên ngoài "công cộng: static struct QMetaObject const Qwt3D :: Plot3D :: staticMetaObject"? (StaticMetaObject @ Plot3D @ Qwt3D @@ 2UQMetaObject @@ B) QT doc đề xuất sử dụng nhiều thừa kế: http://doc.trolltech.com/4.3/uitools-multipleinheritance.html Mặc dù chúng mở rộng QWIdget, tôi cần QObject. – Pete

+2

Liên kết bạn đăng đang hiển thị ví dụ về cách sử dụng các tệp .ui (những tệp được tạo bởi Nhà thiết kế Qt). Một điểm khác biệt quan trọng là Ui :: CalculatorForm không phải là phân lớp của QObject. Quy tắc khi phân lớp từ QObject (và sử dụng đa thừa kế) là chỉ một trong các siêu lớp có thể là QObject và QObject phải là phần đầu tiên trong kế thừa. – ashcatch

+1

tài liệu đề xuất nhiều thừa kế trong một trường hợp khác. khi sử dụng Qt Designer, bạn sẽ nhận được tệp .ui, sau đó một công cụ gọi là uic sẽ lấy tệp .ui đó và tạo một lớp cơ bản là bản dịch của tệp .ui, chỉ trong thực tế C++. vì vậy những gì họ đang đề xuất cơ bản là kế thừa từ lớp đó, thay vì có nó như là một thành viên. –

1

Tôi tin rằng sẽ hoạt động nếu tín hiệu Plot3D :: rotationChanged được công khai hoặc được bảo vệ. Bạn có chắc chắn tín hiệu không phải là riêng tư không?

Edit:

Mặc dù tôi không thể tìm thấy một tài liệu tham khảo cụ thể, tôi sẽ phải kết luận rằng tín hiệu luôn cộng đồng. Ít nhất một bài kiểm tra tôi đã làm ở đây dường như chỉ ra rằng tôi có thể kết nối với một tín hiệu ngay cả khi nó được khai báo trong phần riêng tư của một lớp.

Tôi cũng đã xác minh rằng tín hiệu được khai báo trong QObject có thể được kết nối bằng cách sử dụng lớp con của QObject trong câu lệnh kết nối để tín hiệu chắc chắn là có thể kế thừa. Như tôi thấy trong các câu trả lời và nhận xét khác ở đây, vấn đề phải ở nơi khác.

+0

Hi, Tôi đã thử đưa một từ khóa công khai trước khi từ khóa tín hiệu, nhưng Qt MOC không thích rằng: 1> MOC bao gồm \ qwt3d_plot.h 1> include \ qwt3d_plot.h (143): Lỗi: Tín hiệu có thể không có thông số truy cập 1> Dự án: lỗi PRJ0019: Công cụ trả về mã lỗi từ "MOC include \ qwt3d_plot.h" – Pete

+0

Rất tiếc. Rõ ràng tôi nên sử dụng "công khai: tín hiệu:", nhưng điều đó không giúp được gì. – Pete

0

Không chính xác -> xem nhận xét.

Tôi đang sử dụng Qtopia tại Uni và tôi tin rằng tôi nhớ lại ai đó đang nói gì đó về khoảng trắng trong thông số SIGNAL và SLOT để kết nối.

Hãy thử sử dụng

QObject::connect(this, SIGNAL(rotationChanged(double,double,double)), 
      this, SLOT(myRotationChanged(double,double,double))); 

Tôi biết nó không có vẻ trực quan, như C++ không phải là nhạy cảm với khoảng trắng, tuy nhiên tôi tin rằng nó có cái gì để làm với một số sự kỳ diệu mà Qtopia/QT sử dụng khi kết nối tín hiệu và khe. Điều này chỉ có thể áp dụng cho Qtopia hoặc tôi có thể đã nghe nhầm, nhưng hãy thử. Ngoài ra là các tín hiệu công cộng hoặc được bảo vệ và bạn đã bao gồm các tệp tiêu đề thích hợp chưa?

+0

Tôi hiện có: công khai: tín hiệu: \t \t //! Phát ra, nếu xoay được thay đổi void rotationThay đổi (double xAngle, double yAngle, double zAngle); Trong tiêu đề và thư viện âm mưu, và QObject :: kết nối (this, SIGNAL (rotationChanged (double, double, double)), \t \t này, SLOT (myRotationChanged (double, double, double))); Trong lớp dẫn xuất của tôi ... vẫn lỗi tương tự. Tôi đã bao gồm tiêu đề: #include // có lớp Plot3D – Pete

+0

Khi bạn khai báo các tín hiệu, không khai báo tên cho tham số, chỉ các loại. Đó là công khai: tín hiệu: void voidThay đổi (gấp đôi, gấp đôi, gấp đôi); Hy vọng rằng cần sửa lỗi của bạn. – mdec

+0

Khoảng cách không có hiệu lực tín hiệu & khe, những gì bạn nghe là bình thường hóa tín hiệu/khe mà chỉ tăng tốc chút ít mã nhưng điều đó hầu như không đáng chú ý. – ismail

2

SIGNAL (x) và SLOT (x) là các macro tạo chuỗi ký tự chuỗi. Tại thời gian chạy, các vị trí và tín hiệu được so khớp bằng cách sử dụng so sánh chuỗi của các chữ cái được tạo.

(tôi đã có thêm một nhận xét để bình luận MDEC, nhưng tôi không có đủ đại diện)

+0

Đúng - Tôi nghĩ đó là trung tâm của vấn đề này; vì chuỗi khớp MACRO/MOC kết hợp chỉ tìm kiếm tệp tiêu đề hiện tại cho tín hiệu, nên nó không biết tìm trong thư viện mã biên dịch khác của tôi. – Pete

+0

Pete, tôi chắc chắn bạn đã sai. Các tín hiệu và khe được giữ ở đâu đó (moc tạo mã cho điều này, bạn có thể thấy nó trong tệp * _moc), nó không liên quan gì đến tệp tiêu đề hiện tại. –

+0

(lời nguyền! - Tôi không có đủ đại diện để thêm nhận xét cuối cùng của Pete về lỗi liên kết) Có vẻ như bạn không liên kết trong moc_qwt3D_plot.cpp. –

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