在QT创建者中动态更改x和y坐标

dynamically change x and y coordinates in QT creator

本文关键字:坐标 QT 创建者 动态      更新时间:2023-10-16

我希望在QT中动态传递椭圆的x和y坐标。我尝试了以下操作,但似乎setPos(x, y)函数直到on_pushButton_2_clicked()返回后才真正变换椭圆。

我有两个按钮,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++;
    }
}

任何帮助都将不胜感激。

问题是您的睡眠操作阻塞了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线程,否则你的应用程序会冻结。