2012-02-23 12 views
7

Tôi đang cố gắng mã một hàm gọi lại tĩnh được gọi thường xuyên từ một hàm tĩnh khác trong cùng một lớp. Hàm gọi lại của tôi cần emit một tín hiệu nhưng vì một lý do nào đó, nó chỉ đơn giản là không làm như vậy. Tôi đã đặt nó dưới một trình gỡ lỗi và slot không bao giờ được gọi. Tuy nhiên khi tôi đặt mã tôi sử dụng để emit dữ liệu trong một chức năng không tĩnh nó hoạt động. Có một lý do tôi không thể phát ra một tín hiệu từ một chức năng tĩnh? Tôi đã thử khai báo một thể hiện mới của lớp và gọi hàm emit nhưng không may mắn.Gửi tín hiệu từ phương thức lớp tĩnh trong Qt

class Foo 
{ 
signals: 
    emitFunction(int); 
private: 
    static int callback(int val) 
    { 
     /* Called multiple times (100+) */ 
     Foo *foo = new Foo; 
     foo.emitFunction(val); 
    } 
    void run() 
    { 
     callback(percentdownloaded); 
    } 
}; 

Tôi đã đăng một số mã cơ bản thể hiện những gì tôi đang cố gắng làm. Tôi sẽ đăng mã đầy đủ theo yêu cầu.

Chỉnh sửa: Tôi đăng toàn bộ mã vì đây là loại kịch bản lạ. http://pastebin.com/6J2D2hnM

+1

Nơi nào bạn kết nối tín hiệu và SLOT? – Nobody

+0

Tôi kết nối chúng trong một tệp '.cpp' riêng biệt được gọi trên một nút bấm. 'void MainWindow :: on_pushButton_clicked() { tProc = new Foo (điều này); kết nối (tProc, SIGNAL (ValChanged (int)), điều này, SLOT (onNumberChanged (int))); tProc-> start(); } 'nó sau đó tạo một thể hiện mới của lớp' Foo' của tôi và bắt đầu luồng gọi hàm gọi lại. – user99545

+0

Trong hàm gọi lại tĩnh của bạn, bạn tạo một cá thể Foo mới và gọi tín hiệu trên đó. Tôi cho rằng đây là điểm mà bạn muốn phát ra tín hiệu. Làm thế nào để bạn kết nối cá thể này với vị trí bạn muốn giải quyết? – Nobody

Trả lời

10

Điều đó sẽ không hoạt động, vì bạn đang tạo Foo mới mỗi khi bạn nhập hàm tĩnh đó và bạn không kết nối tín hiệu với khe.

Vì vậy, việc sửa chữa sẽ là để vượt qua các đối tượng đến chức năng mà:

class Foo 
{ 
signals: 
    emitFunction(int); 
private: 
    static int callback(int val, Foo &foo) 
    { 
     /* Called multiple times (100+) */ 
     foo.emitFunction(val); 
    } 
    void run() 
    { 
     callback(percentdownloaded, *this); 
    } 
}; 

Một lựa chọn khác là sử dụng postEvent, nhưng tôi sẽ không khuyên bạn nên nó.


Vì bạn không thể sửa đổi chữ ký callback, bạn có thể làm điều đó như thế này:

class Foo 
{ 
signals: 
    emitFunction(int); 
private: 
    static int callback(int val) 
    { 
     /* Called multiple times (100+) */ 
     theFoo->emitFunction(val); 
    } 
    static Foo *theFoo; 
    void run() 
    { 
     callback(percentdownloaded, *this); 
    } 
}; 

nhưng bạn sẽ phải khởi tạo rằng biến tĩnh ở đâu đó.

+0

Điều này sẽ hoạt động, nhưng vấn đề là hàm gọi lại tĩnh của tôi đang được gọi bởi một hàm khác từ thư viện libCURL và tôi không thể chuyển đối số cho nó. Tôi không chắc chắn làm thế nào để thực hiện phương pháp của bạn trong trường hợp này. – user99545

+1

@ user99545 ​​thêm biến tĩnh, được sử dụng trong gọi lại. Tôi sẽ chỉnh sửa câu trả lời –

+0

Cảm ơn. Tôi đã kết thúc bằng cách sử dụng biến tĩnh của bạn và khởi tạo nó bằng cách truyền thể hiện lớp hiện tại làm tham số cho luồng. Tôi đã sử dụng tham số đó để khởi tạo lớp và nó hoạt động. – user99545

0

Bạn phải cung cấp con trỏ đến cá thể lớp để làm cho nó hoạt động.

Tuy nhiên, thông báo nói chung, không nên phát ra tín hiệu từ các chức năng tĩnh. Các hàm tĩnh có thể được gọi mà không tạo ra một thể hiện của lớp, có nghĩa là (nếu bạn không cung cấp đối số người gửi và sử dụng nó một cách rõ ràng), bạn sẽ không có đối tượng "người gửi" cho các tín hiệu được phát ra.

Đối với những trường hợp này vì Lol4t0 gợi ý tôi cũng thích gọi lại.

2

trong trường hợp ai đó vẫn đang tìm giải pháp, dưới đây là những gì tôi đã làm, nó hoạt động trong dự án của tôi. 1. làm cho lớp học của bạn trở thành một singleton 2. chức năng cb tĩnh, emitFunction tải từ lớp singleton bạn

static int callback(int val) 
    { 
    /* Called multiple times (100+) */ 
    MYClass::getInstance()->emitFunction(val); 
    } 
+0

cách tiếp cận tốt đẹp và đơn giản, nó thậm chí là luồng an toàn kể từ khi phát ra tín hiệu. +1 – g24l