2011-01-14 65 views
5

Tôi đã làm việc này trong nhiều giờ và không thể tìm ra và cũng không thể tìm thấy bất kỳ trợ giúp trực tuyến nào hoạt động. Về cơ bản ý chính của những gì tôi đang cố gắng thực hiện là có một GUI Qt với một nút và một QTextBrowser. Khi tôi nhấn nút, tôi muốn nó gửi một tin nhắn và sau đó tiếp tục in tin nhắn này sau mỗi 10 giây.Qt: Làm thế nào để sử dụng QTimer để in một tin nhắn đến một QTextBrowser mỗi 10 giây?

Tôi đã tìm tôi sẽ sử dụng QTimer vì có ý nghĩa khi có bộ đếm thời gian để gửi lại tin nhắn mỗi 10 giây. Khi tôi ban đầu thực hiện điều này vào buttonClicked() SLOT của tôi nó gây ra chương trình đóng băng. Tôi đã xem trực tuyến một giải pháp và tìm thấy QApplication :: processEvents().

Vì vậy, về cơ bản trong chức năng của tôi, tôi có một cái gì đó như thế này:

while(1) 
{ 
    QTimer *timer; 
    connect(...) //omitted parameters for this example  
    timer.start(10000); 
    ui->diplay->append("Message"); 

    while(timer.isActive()) 
    { 
     QApplication::processEvents() 
    } 
} 

tôi figured nó sẽ thoát ra khỏi timer.isActive() trong khi vòng lặp nhưng nó sẽ không chỉ đơn giản là nó vẫn ở đó.

Vì vậy, tôi đã tìm ra đây là vấn đề về luồng. Vì vậy, tôi đã tìm ra cách sử dụng QThreads nhưng tôi vẫn không thể làm cho nó hoạt động. Về cơ bản khi tôi tạo một thread với một bộ đếm thời gian trên nó và các thread nói với bộ đếm thời gian để bắt đầu, chương trình đóng và giao diện điều khiển nói "Chương trình đã bất ngờ hoàn thành".

Cần phải có một cách dễ dàng để làm điều này nhưng hồ sơ theo dõi của tôi với Qt luôn rằng thứ

+0

UPDATE: Tôi bây giờ sử dụng timer-> singleShot (hẹn giờ, SIGNAL (timeout()), này, SLOT (cập nhật())) ; Nhưng tôi cần chương trình in tin nhắn và đợi 10 giây trước khi nó tiếp tục xử lý. Tôi có nó trong một vòng lặp while nên nó liên tục làm singleShots thay vì cứ 10 giây một lần. Bất kỳ đề xuất? Cảm ơn! –

+1

Có phải gần như tất cả mọi người đã bỏ lỡ một thực tế rằng điều này đang xảy ra trong một vòng lặp (1)? Không có gì lạ khi chương trình bị đóng băng. –

Trả lời

6

Nếu bạn muốn hiển thị thông điệp của bạn cho 10s, cách tốt hơn để làm điều đó, là để tạo ra một trong ứng dụng của bạn sẽ xóa thông báo. Sau đó, trong nút của bạn nhấp khe, thêm tin nhắn của bạn và khởi tạo một bộ đếm thời gian mà sẽ kích hoạt khe nhắn remove của bạn trong 10s:

QTimer::singleShot(10000, this, SLOT(eraseMessageSlot())); 

Ngoài ra, không có nhu cầu về một chủ đề đó ...

+0

Tôi nghĩ rằng tôi cần các chủ đề vì nó bị đóng băng nhưng dường như tôi đã có một kết nối không chính xác. –

+0

Vui lòng xem lại CẬP NHẬT của tôi trong OP. Cảm ơn! –

4

của bạn mã có nhiều vấn đề - tôi giả sử nó là mã giả, về cơ bản, vì timer không tồn tại và những thứ như thế.

Kiểm tra tham chiếu QTimer. Nó có một ví dụ:

QTimer *timer = new QTimer(this); 
connect(timer, SIGNAL(timeout()), this, SLOT(update())); 
timer->start(1000); 

Về cơ bản, bạn muốn thực hiện một khe mà gắn thêm, sau đó kết nối nó với tín hiệu timeout và bắt đầu hẹn giờ. Bộ đếm thời gian sẽ đánh dấu và mỗi giây sẽ gọi khe. Trong trường hợp của bạn, bạn sẽ thay đổi 1000 thành 10000

Nếu cách này không hiệu quả, bạn đang gặp phải vấn đề gì? Tôi không hiểu tại sao bạn đang sử dụng các chủ đề, trừ khi bạn cần chúng.

EDIT Nhìn vào bản cập nhật của bạn, bạn nói rằng bạn muốn đợi 10 giây. Thay vì bận chờ đợi, tại sao không tiếp tục chương trình trong khe của bạn (được gọi là singleShot)? Tôi nghĩ rằng bạn đang thiếu một số triết lý Qt ...

+0

Đây là cơ bản những gì tôi có. Có vẻ như tôi đã quên 'tham số này' và không nhận thấy. Khá lame xem xét tôi đã sử dụng một tuyên bố kết nối một vài dòng ở trên nó với các thông số chính xác. Đối với một số lý do trình biên dịch không hét lên với tôi mặc dù. –

1

Theo mặc định, QTimer sẽ kích hoạt mọi khoảng thời gian cho đến khi bạn dừng nó. Đó là lý do tại sao timer.isActive() luôn đúng. Sử dụng timer.setSingleShot(true) để chỉ bật hẹn giờ. (Hoặc sử dụng QTimer::singleShot như trong bài đăng của @ tibur.)

1

Tôi nghĩ OP muốn hiển thị thông báo lặp đi lặp lại sau mỗi 10 giây?

Trong trường hợp đó chỉ cần tạo bộ hẹn giờ, hãy kết nối khe chức năng updateDisplay() với tín hiệu hẹn giờ và khởi động bộ hẹn giờ.

4

Nó sẽ được tốt hơn để tổ chức các chương trình của bạn như thế này:

class MainWindow : QWidget //or any other parent class 
{ 
public: 
MainWindow() 
{ 
    QPushButton *button = new QPushButton(this); 
    browser_ = new QTextBrowser(this); //and some params maybe 
    QVBoxLayout * layout = new QVBoxLayout(this); //can be used another layout 
    layout->addWidget(button); 
    layout->addWidget(browser_); 

    connect(button, SIGNAL(pressed()), 
     this, SLOT(onButtonPressed())); 

    timer_ = new QTimer(this); 
    connect(timer, SIGNAL(timeout()), 
     this, SLOT(timerHandler())); 
    } 
    ~MainWindow(); 

public slots: 
    void onButtonPressed() 
    { 
     timerHandler(); //to display message when button is pressed 
     if (!timer->isActive()) timer->start(TIMER_INTERVAL); //TIMER_INTERVAL = 10000; 
    } 
    void timerHandler() 
    { 
     //put your code to display message here 
    } 

private: 
    QTextBrowser *browser_; 
    QTimer *timer_; 
} 
+0

Đây là cách nó nên được cấu trúc trong Qt. Cứ sau 10 giây, bộ hẹn giờ sẽ gọi hàm timerHandler. Trong chức năng đó, chỉ cần thêm thông điệp của bạn và thoát khỏi chức năng. Đơn giản và trực tiếp, và quan trọng nhất, không có vòng lặp vô hạn gây ra chương trình đóng băng. –

+0

Tôi thấy một vấn đề với onButtonPressed(). Nó sẽ gọi timerHandler() bất kể bộ hẹn giờ có hoạt động hay không. Theo như tôi có thể nói với bộ đếm thời gian không có gì ở đây ngoại trừ thiết lập lại chính nó sau khi thời gian đã trôi qua. Mã này sẽ chỉ hiển thị thông báo mỗi khi bạn nhấn nút theo như tôi có thể nói. –

+0

Bộ hẹn giờ được kích hoạt khi nút được nhấn vào vị trí trên nútButtonPressed(); bởi vì nếu (! timer-> isActive()) timer-> start (TIMER_INTERVAL); sẽ được gọi – Andrew

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