2013-03-01 31 views
10

Tôi đang sử dụng thư viện QtSerialPort để nói chuyện với cổng COM ảo qua USB. Cổng COM trả về dữ liệu và hoạt động đúng khi thử nghiệm nó với các dự án ví dụ được đưa ra với QtSerialPort, nhưng không thành công khi tôi chạy nó như là một phần của dự án của tôi.QtSerialPort khởi tạo sai chuỗi, khiến tín hiệu/vị trí bị lỗi

Tôi đã kiểm tra chuỗi và chuỗi khởi tạo dẫn đến QtSerialPort được khởi tạo và thấy có gì đó hơi lạ. Các kết quả dưới đây.

main() 
    MainWindow (Thread 0xbf8dbe0)  // Thread "A" 
    HardwareManager (Thread 0xbf8dbe0) // Thread "A" 
     QSerialPort (Thread 0xbfb95f0) // Thread "B" !? 

Trong mã của tôi, hàm main() khởi tạo một phần mềm MainWindow, lần lượt tạo một HardwareManager và lưu nó dưới dạng biến riêng tư. Khi HardwareManager được khởi tạo, nó cũng khởi tạo thể hiện QSerialPort để nó có thể nói đúng với cổng COM.

Tuy nhiên, bạn sẽ nhận thấy trên QSerialPort của tôi là trong một thread khác so với đối tượng phụ huynh, cũng như nó là đối tượng cha mẹ (Đó là trong Thread B, trong khi cả hai tổ tiên là trong Chủ đề A). Tôi nghĩ rằng chủ đề khác này đang gây ra tín hiệu/Slots của tôi thất bại. Nếu tôi dumpObjectInfo, nó sẽ liệt kê Tín hiệu/Khe cắm của tôi khi được thiết lập, nhưng các sự kiện sẽ không bao giờ kích hoạt.

this->serial = new QSerialPort(); 
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData()); 

Phía trên là mã mà tôi sử dụng để tạo cổng nối tiếp mới và kết nối với khe thích hợp. Cấu hình baud, chẵn lẻ và dữ liệu/dừng bit thực tế xảy ra riêng biệt (và hoạt động đúng, như được kiểm tra trong ứng dụng ví dụ được cung cấp bởi QtSerialPort).

Có ai có bất kỳ thông tin chi tiết nào về lý do tại sao đối tượng cụ thể này (cá thể QSerialPort) đang được khởi tạo trong một luồng khác không? Tôi đã thử "moveToThread" để chuyển đổi các liên kết thread, nhưng không có gì có vẻ làm việc.

Tôi cũng đã thực hiện một post on the Qt Project Forums nhưng chưa có phản hồi hữu ích nào.

Edit: Sau đây là mã có liên quan trong chuỗi cuộc gọi:

// main() 
QApplication a(argc, argv) 
MainWindow window = new MainWindow(); // [1] 
MainWindow.show(); 
return a.exec(); 

// MainWindow::MainWindow() [1] 
this->toolController = new QtToolController(this); 
HardwareManager *manager = new HardwareManager(this->toolController); // [2] 

// HardwareManager::HardwareManager() [2] 
this->serial = new QSerialPort(); 
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData())); 

Khi một QSerialPort sẵn sàng để được đọc từ (nó có dữ liệu để cung cấp), nó cháy tín hiệu readyRead (ít nhất, nó được cho là). Tín hiệu này kích hoạt đúng trong các dự án ví dụ Qt, nhưng tôi không bao giờ nhận được tín hiệu trong ứng dụng của mình. Tôi tin rằng lý do tôi không nhận được tín hiệu là vì những vấn đề thread.

+1

Tôi không biết QT hoạt động như thế nào, do đó, chỉ là một dự đoán hoang dã: bạn có đang tạo ra 'QSerialPort' để phản hồi một số sự kiện không? Bất kỳ cơ hội nào mà trình xử lý sự kiện được gọi trong ngữ cảnh của các luồng khác nhau? –

+0

Không. Sự khởi tạo QSerialPort nằm trong phần khởi tạo HardwareManager, tức là trong sự khởi tạo MainWindow, được gọi trong phương thức main(). Tại thời điểm này, không có tín hiệu/khe/callbacks đang được sử dụng. –

+0

Tôi tin rằng bạn không nên bận tâm về chủ đề khác, bạn nên bận tâm về không chỉ tín hiệu/khe. Cho chúng tôi thấy chính của bạn, xin vui lòng. Và cung cấp một số thông tin về thời điểm nên kích hoạt – ixSci

Trả lời

1

Với tinh thần giữ các câu trả lời có sẵn cho bất kỳ ai khác gặp sự cố này, sự cố có liên quan đến bản phát hành Bản phát hành/Gỡ lỗi. Thư viện QtSerialPort đã được xây dựng chỉ dành cho môi trường phát hành của tôi, và vì lý do gì đó, khi chạy ứng dụng của tôi trong chế độ Debug sẽ liên kết đến Release QtSerialPort, và các bối cảnh chủ đề sẽ bị mất.

Để khắc phục điều này, tôi đảm bảo rằng tôi đã xây dựng phiên bản thư viện phù hợp và sau đó đảm bảo tôi liên kết với đúng phiên bản cho môi trường của mình.

2

Bạn có thể sử dụng QueuedConnection để nhận tín hiệu từ một chuỗi khác.

connect(this->serial, SIGNAL(readyRead()), 
    this, SLOT(readSerialData()), Qt::QueuedConnection); 

Bằng cách này, vị trí sẽ được thực hiện trong ngữ cảnh của chuỗi chính khi điều khiển trở lại vòng lặp sự kiện của nó.

Ngoài ra, this post dường như đề xuất rằng bạn không nên đặt cha mẹ cho QtSerialPort (có thể vì moveToThread không hoạt động trên QObject với cha mẹ).

+0

Thêm tham số Qt :: QueuedConnection không cần thiết, vì mặc định Qt :: AutoConnection (Tôi đang sử dụng Qt 5, không chắc chắn về Qt 4) cũng xử lý các kết nối giữa các luồng khác nhau một cách chính xác. – FourtyTwo

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