如何截获转换的结束:QT QML 中的旋转操作



我的QML文件中有一个箭头的图像。我想将其旋转到特定位置。该位置由C++代码设置。在C++代码中,我有一个 QThread,它每 1 毫秒更改一次位置的值。在这种情况下,之前的旋转不会结束(我想),并且在显示屏中我看到前一个位置的"回声"。我想避免仓位值的变化,直到上一次旋转结束。例如:如果我将位置设置为 40,并且执行旋转需要 3 毫秒,则在接下来的 3 毫秒内,C++代码不必更改位置。QML 文件:

Item {
    id: speedo
    property real speedvalue: 20
    property real prevspeedvalue: 20
    property string numero: "000000000";
    property alias tachiText: tachi.text
    x:0
    y:0
    width:1400
    height:540
    Rectangle
    {
        x:0
        y:0
        width:1400
        height:540
        color: "black"
    }
    Image {
        source:"BigDash_images/sfondo.png"
        id:sfondo
        x:0 ; y:0
        width:1400 
        height:540 
    }
    Image {
        source:"BigDash_images/meter_wheel.png"
        id:meter_wheel
        x:430 ; y:13
        width:539 
        height:513 
    }
    Text {
        text:'02478981' 
        font.pixelSize:22
        color:Qt.rgba(1, 1, 1, 1)
        id:tachi
        x:627 ; y:390
        width:148 
        height:33 
        font.letterSpacing : 5
    }
    Image {
        source:"BigDash_images/indicatore.png"
        id:indicatore
        x:556 ; y:256
        width:192
        height:143
        transform: Rotation {origin.x: 142; origin.y:46; angle:(speedo.speedvalue-20)*1.25}
        smooth: true
    }
    Image {
        source:"BigDash_images/color_adjustments.png"
        id:color_adjustments
        x:0 ; y:0
        width:1 
        height:1 
    }
}

主.cpp

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QApplication> app(createApplication(argc, argv));
    QWSDisplay::setTransformation(QTransformedScreen::Rot180, 0);
    QDeclarativeView mainView;
    mainView.setResizeMode(QDeclarativeView::SizeRootObjectToView);
    mainView.setSource(QUrl::fromLocalFile("BigDashboard/BigDash.qml"));
    mainView.setAttribute(Qt::WA_AutoOrientation,true);
    mainView.showFullScreen();
    QObject *object = (QGraphicsObject *)mainView.rootObject();
    Threddi th(object);
    th.start();
    return app->exec();
}

旋转Q读取代码:

Threddi::Threddi(QObject *pobj)
{
    m_pView = pobj;
    m_pFreccia  = m_pView->findChild<QObject *>("indicatore");
}
#define GRANO ((int)1)
void Threddi::run()
{
    int verso = GRANO;
    int prepos = 20;
    int pos = 20;
    int numero = 0;
    while (1)
    {
        QThread::msleep(1);
        prepos = pos;
        pos+=verso;
        if (pos>=220)
        {
            verso = -GRANO;
            pos+=verso;
        }
        else if (pos<=20)
        {
            verso = GRANO;
            pos+=verso;
        }
        if (m_pView!=NULL)
        {
            m_pView->setProperty("speedvalue",pos);
        }
        else
            printf("m_pView == NULL!!!!!nr");
    }
}

有什么想法吗?

舒班加我以这种方式实现了您的建议:在 QML 文件中,我放置了一个名为 abilitato 的新属性。onAngleChanged 将此属性设置为 1。在C++代码中,如果abilitato为 1,则abilitato = 0并更改位置。结果和以前一样。我认为角度变化是在更改属性时发出的,而不是在旋转完成时发出的。

C++ 代码片段:

QVariant a = m_pView->property("abilitato");
int val = a.toInt();
if (val == 1)
{
m_pView->setProperty("abilitato",0);
m_pView->setProperty("speedvalue",pos);
}

QML 文件片段:

property real abilitato: 1
transform: Rotation                    
{                                      
origin.x: 142;                     
origin.y:46;                       
angle:(speedo.speedvalue-20)*1.25  
onAngleChanged: speedo.abilitato= 1
}

从您的代码中我了解到您正在设置属性

m_pView->setProperty("speedvalue",pos);

这会更改图像的旋转。当您执行此操作时,您不知道之前的旋转是否已结束。为了确保在完成先前的旋转后将新的旋转值应用于图像,必须在QML端做出决定。所以我的想法如下(请注意,我没有尝试过你的代码)

1)在线程中计算图像的新旋转值时,请勿设置 speedvalue 属性。而是将新speedvalue存储在队列中。

2)在QML端,一旦图像的旋转完成,onAngleChanged:您可以从队列中读取speedValue的下一个值并使用它来设置新angle。请记住在读取读取值后将其从队列中删除。

我想

再次声明,我没有测试过上述想法。

最新更新