2015-11-02 223 views
0

我希望在QT中動態傳遞橢圓的x和y座標。我已經嘗試了以下內容,並且看起來setPos(x, y)函數實際上並不實際轉換橢圓,直到on_pushButton_2_clicked()返回。動態更改QT創建器中的x和y座標

我有兩個按鈕,pushButton1pushButton2,第一個是創建橢圓(並確保一個被調用時不會創建另一個),另一個應該更改傳遞的座標。

void MainWindow::on_pushButton_clicked() 
{ 
    int hasRun = 0; 
    while(!hasRun) 
    { 
    QBrush green(Qt::green); 
    QBrush blue(Qt::blue); 
    QPen blackPen(Qt::black); 
    blackPen.setWidth(2); 
    ellipse = scene -> addEllipse(10, 10, 25, 25, blackPen, green); 
    hasRun = 1; 
    flag = 1; 
    } 
} 

void MainWindow::change(int x, int y) 
{ 
    ellipse->setPos(x, y); 
    cout << "width: " << ui->graphicsView->width() << endl; 
    cout << "height: " << ui->graphicsView->height() << endl; 
} 

void MainWindow::on_pushButton_2_clicked() 
{ 
    int i = 0; 
    while(i < 25) 
    { 
    change(i, i); 
    Sleep(200); 
    i++; 
    } 
} 

任何和所有的幫助,將不勝感激。

回答

1

問題是,你正在用你的睡眠操作阻塞UI線程,這意味着UI永遠不會重繪,所以你看不到你的UI更新,直到點擊函數返回。

解決此問題的最簡單方法是使用QTimer 1,它允許您在將來安排事件。當計時器到期(超時)時,它會調用你的事件處理程序。但是,它在等待時不會阻塞UI線程。你可以使用像這樣達到預期的動畫效果:

auto timer = new QTimer(this); 

// Define the timeout slow for the timer. 
connect(timer, &QTimer::timeout, [timer, ellipse]() { 
    auto x = ellipse->x(); 
    auto y = ellipse->y(); 

    // If we have reached our target position, stop the timer. 
    if (x == 25) { 
    timer->stop(); 
    return; 
    } 

    // Otherwise update the position. 
    ellipse->setPos(x + 1, y + 1); 
}); 

// Start the timer. The timeout slot we defined above will be called every ~200ms. 
timer->start(200); 

一個更好的方法來做到這一點是使用通過QPropertyAnimation 2 Qt的動畫支持,它允許您設置開始和結束時間,一個屬性的值,然後會自動插入它們之間。請參閱文檔以獲取使用示例。然而,對於你的情況,因爲你不是動畫QObject子類,你不能只是這個。

一般來說,如果您需要執行耗時的任務,您應該在後臺線程上這樣做,以避免阻塞UI線程,否則您的應用程序將凍結。