2009-06-10 12 views
5

Tôi có bảng điều khiển QCoreApplication dựa trên bảng điều khiển có bộ hẹn giờ và truyền thông ổ cắm cũng như sử dụng mutex bị khóa.Dọn dẹp trước khi đóng QCoreApplication

Khi tôi đóng ứng dụng theo cách thủ công, nó cho biết lỗi nói rằng một số mutex bị khóa và đã hết thời gian chờ. Có cách nào tôi có thể làm sạch trong một ứng dụng giao diện điều khiển khi người dùng đóng nó?

Trả lời

15

Dọn dẹp phải được xử lý bởi các mối phá hủy và mối quan hệ giữa cha và con.

Làm cho đối tượng chính của bạn (đối tượng chính) là con của QApplication vì vậy nó bị hủy với tất cả các con của nó trước khi QApplication là.

Bạn có chắc chắn đã giết tất cả các chủ đề của mình không? Nếu nó là một chủ đề với một eventloop hãy chắc chắn để gọi QThread::quit() để thoát khỏi eventloop trước khi bạn gọi QThread::wait()

Bạn cũng có thể sử dụng khoảng trống QApplication::qAddPostRoutine (QtCleanUpFunction ptr) để làm một số ngẫu nhiên đặc biệt.

Để gỡ lỗi những thư bạn có thể sử dụng QtMsgHandler qInstallMsgHandler (QtMsgHandler h) và viết trình xử lý tin nhắn của riêng bạn để nắm bắt những cảnh báo đó. Nếu bạn có thể mô phỏng sự cố, bạn có thể đặt điểm ngắt trên thư và xem trên ngăn xếp nơi thư đến.

void debugMessageHandler(QtMsgType type, const char *msg){ 
    if(QString(msg).contains("The message you can see in the console")){ 
     int breakPointOnThisLine(0);  
    } 

    switch (type) { 
     case QtDebugMsg: 
      fprintf(stderr, "Debug: %s\n", msg); 
      break; 
     case QtWarningMsg: 
      fprintf(stderr, "Warning: %s\n", msg); 
      break; 
     case QtFatalMsg: 
      fprintf(stderr, "Fatal: %s\n", msg); 
      abort(); 
    } 
} 

Để dọn dẹp với tàu destructor và trẻ em cha mẹ mối quan hệ bạn có thể nắm bắt những tín hiệu gần console và gọi QCoreApplication::exit() đến dụ ứng dụng.

#include <csignal> 
#include <QtCore/QCoreApplication> 
using namespace std; 

struct CleanExit{ 
    CleanExit() { 
     signal(SIGINT, &CleanExit::exitQt); 
     signal(SIGTERM, &CleanExit::exitQt); 
     signal(SIGBREAK, &CleanExit::exitQt) ; 
    } 

    static void exitQt(int sig) { 
     QCoreApplication::exit(0); 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    CleanExit cleanExit; 
    QCoreApplication a(argc, argv); 
    return a.exec(); 
} 
+0

gần như hoàn tất.một khi bạn đã gọi exit (0), bạn phải làm mã Qt cụ thể của bạn dọn dẹp một nơi nào đó mà không phải là trong handler tín hiệu exitQt(). do đó, bạn phải buộc mã dọn dẹp Qt của bạn với tín hiệu aboutToQuit(). tín hiệu aboutToQuit chỉ phát ra khi qApp-> exit (0) được gọi. –

+2

C++ 11 làm cho nó dễ dàng hơn: 'tín hiệu (SIGTERM, [] (int sig) {qApp-> quit();});' – ManuelSchneid3r

+0

Điều này không hoạt động đầy đủ. Tôi đã làm cho đối tượng liên quan đến dọn dẹp là một đứa trẻ của QApplication. Các destructor được gọi là đúng khi cửa sổ đóng cửa bình thường. Nhưng khi tắt hệ thống/đăng xuất, trình phá hoại con QApplication không bao giờ được gọi. – galinette

1

bạn có thể kết nối với tín hiệu QCoreApplication::aboutToQuit và thực hiện việc dọn dẹp cần thiết ở đó.

+2

Xin chào Daniel, Tôi đã thử điều này, nhưng điểm ngắt không đạt được trong SLOT được kết nối. tài liệu nói về tín hiệu AboutToQuit được phát ra khi thoát trên QCoreApplication được gọi. Có đóng ứng dụng giao diện điều khiển gọi quit()? Cảm ơn, Suresh. –

5

Hóa ra rằng đóng ứng dụng dòng lệnh (kiểm tra trên Win7 & VS2010) bằng cách nhấn 'gần' (nút x màu đỏ trên thanh tiêu đề) vượt qua STATUS_CONTROL_C_EXIT tín hiệu vào ứng dụng. Tất cả các chủ đề đều bị hủy bỏ với mã này.

Chủ đề 'Chủ đề chính' (0x980) đã thoát với mã -1073741510 (0xc000013a).

Chủ đề 'QThread' (0x2388) đã thoát với mã -1073741510 (0xc000013a).

Điều đó có nghĩa là không có cách nào để chặn điều này với tín hiệu QCoreApplication::aboutToQuit().

Hãy xem winnt.h hoặc ntstatus.h. Đó là giá trị được gán cho hằng số kê khai STATUS_CONTROL_C_EXIT. Thời gian chạy chỉ là chọn kết thúc chương trình của bạn bằng mã để lưu ý thao tác hủy của người dùng .

+0

Sử dụng SetConsoleCtrlHandler() để chặn những điều này và gọi qApp-> thoát (42) – Macke