2012-06-17 56 views
1

我想爲我的女朋友學士論文寫一個改變失明程序。它顯示X毫秒的圖片,顯示一個短的「閃爍圖像」(在這種情況下只是灰色),然後顯示與第一個圖像稍有不同的圖像。然後再一次閃爍的圖像。QGraphicsView閃爍

然後所有東西都從頭開始。它工作正常,只有圖形工件。畫布/ QGraphicsView刷新速度不夠快,所以它們在刷新過程中是「線條」。

要顯示圖像的時間:70毫秒,閃爍時間:30毫秒。所以它的每秒100毫秒= 10 FPS。我雖然這可能沒有使用GPU。但它看起來不是。

我可以使用雙緩衝還是可以避免GPU的東西?或者我需要使用QGL嗎?其大約1兆字節的圖像。

我加載他們一次,只是顯示他們我認爲。也許我在現場做錯了事。

我會附上我的源代碼,也許你有一些想法。

親切的問候:)

#ifndef PICTURES_H 
#define PICTURES_H 

#include <QMainWindow> 
#include <QImage> 
#include <QPixmap> 
#include <QGraphicsPixmapItem> 
#include <iostream> 
#include <QDir> 
#include <QGraphicsScene> 
#include <QDebug> 
#include <QTimer> 


namespace Ui { 
class pictures; 
} 

class pictures : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit pictures(QWidget *parent = 0); 
    ~pictures(); 

    void loadPics(); 
    void showPics(); 

public slots: 
    void stopClicked(); 
    void clearPictures(); 
    void timePassed(); 
    void changeImage(); 
    void changeImageGrey(); 

private: 
    int counter; 
    int image_counter; 
    int stop_time; 
    Ui::pictures *ui; 
    QVector<int> times; 
    QTimer* timer; 
    QTimer* timerImageChange; 
    QTimer* timerGrey; 

    int imageChangeTime; 
    int greyTime; 

    QVector<QGraphicsPixmapItem*> images; 
    QGraphicsScene* scene; 
    QGraphicsScene* scene_grey; 
    QGraphicsPixmapItem* item1; 
}; 

#endif // PICTURES_H 


#include "pictures.h" 
#include "ui_pictures.h" 

pictures::pictures(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::pictures), times() 
{ 
    counter = 1; 
    stop_time = 0; 
    image_counter = 0; 
    timer = new QTimer(this); 
    timerGrey = new QTimer(this); 
    timerImageChange = new QTimer(this); 
    connect(timer, SIGNAL(timeout()), this, SLOT(timePassed())); 
    connect(timerImageChange, SIGNAL(timeout()), this, SLOT(changeImageGrey())); 
    connect(timerGrey, SIGNAL(timeout()), this, SLOT(changeImage())); 

    greyTime = 200; 
    imageChangeTime = 500; 


    qDebug() << "Hello im here in pictures"; 

    ui->setupUi(this); 
    this->loadPics(); 
    connect(ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(stopClicked())); 
    connect(ui->pushButtonNext, SIGNAL(clicked()), this, SLOT(clearPictures())); 

    timer->start(10); 
    timerImageChange->start(imageChangeTime); 
} 

pictures::~pictures() 
{ 
    delete ui; 
} 

void pictures::loadPics() 
{ 
    qDebug() << QDir::toNativeSeparators((QDir::current().absolutePath() + QDir::separator() + "debug" + QDir::separator() + "pics" + QDir::separator() + QString::number(counter) + QDir::separator()+"1.jpg")); 
    //QImage imageOne(QDir::toNativeSeparators(QDir::current().absolutePath() + QDir::separator() + "debug" + QDir::separator() + "pics" + QDir::separator() + QString::number(counter) + QDir::separator()+"1.jpg")); 
    //QImage imageTwo(QString("./pics/")+counter+"/2.png"); 
    //QImage imageThree(QString("./pics/")+counter+"/3.jpg"); 
    //QImage imageFour(QString("./pics/")+counter+"/2.png"); 

    images.append(new QGraphicsPixmapItem(QDir::toNativeSeparators(QDir::current().absolutePath() + QDir::separator() + "debug" + QDir::separator() + "pics" + QDir::separator() + QString::number(counter) + QDir::separator()+"1.jpg"))); 
    images.append(new QGraphicsPixmapItem(QDir::toNativeSeparators(QDir::current().absolutePath() + QDir::separator() + "debug" + QDir::separator() + "pics" + QDir::separator() + QString::number(counter) + QDir::separator()+"2.jpg"))); 
    images.append(new QGraphicsPixmapItem(QDir::toNativeSeparators(QDir::current().absolutePath() + QDir::separator() + "debug" + QDir::separator() + "pics" + QDir::separator() + QString::number(counter) + QDir::separator()+"3.jpg"))); 
    images.append(new QGraphicsPixmapItem(QDir::toNativeSeparators(QDir::current().absolutePath() + QDir::separator() + "debug" + QDir::separator() + "pics" + QDir::separator() + QString::number(counter) + QDir::separator()+"4.jpg"))); 


    //QGraphicsPixmapItem* item1(QPixmap::fromImage(imageOne)); 
    item1 = images[image_counter]; 
    //QGraphicsPixmapItem item2(QPixmap::fromImage(imageTwo)); 
    //QGraphicsPixmapItem item3(QPixmap::fromImage(imageThree)); 
    //QGraphicsPixmapItem item4(QPixmap::fromImage(imageFour)); 
    scene = new QGraphicsScene; 
    scene_grey = new QGraphicsScene; 

    int maximum = item1->boundingRect().width() > item1->boundingRect().height() ? item1->boundingRect().width() : item1->boundingRect().height(); 
    int dimension_width = ui->graphicsView->rect().width(); 
    int dimension_height = ui->graphicsView->rect().height(); 

    //int biggest_canvas_dimension = (((float)item1->boundingRect().width())/dimension_width) > (((float)item1->boundingRect().height())/dimension_height) ? dimension_width : dimension_height; 
    int biggest_canvas_dimension = dimension_width > dimension_height ? dimension_width : dimension_height; 

    if(maximum > ui->graphicsView->rect().width() || maximum > ui->graphicsView->rect().height()) 
    { 
     dimension_width = (int) (item1->boundingRect().width() * ((float)(biggest_canvas_dimension)/maximum)); 
     dimension_height = (int) (item1->boundingRect().height() * ((float)(biggest_canvas_dimension)/maximum)); 
     item1->setPixmap(item1->pixmap().scaled(dimension_width,dimension_height)); 

     qDebug() << "Width: " << dimension_width << " Height " << dimension_height << " Pic High" << item1->boundingRect().height(); 
    } 

    //item1->setPixmap(item1->pixmap().scaled(QSize(ui->graphicsView->rect().width(), ui->graphicsView->rect().height()))); 
    scene->setSceneRect(ui->graphicsView->rect()); 
    scene->addItem(item1); 

    scene_grey->setSceneRect(ui->graphicsView->rect()); 
    scene_grey->addItem(images[1]); 


    ui->graphicsView->setScene(scene); 
    ui->graphicsView->adjustSize(); 

    //ui->graphicsView->show(); 


} 

void pictures::timePassed() 
{ 
    stop_time += 10; 
} 

void pictures::stopClicked() 
{ 
    timerImageChange->stop(); 
    timerGrey->stop(); 
    times.append(stop_time); 
    ui->pushButtonStop->setEnabled(false); 
    ui->pushButtonNext->setEnabled(true); 
    counter++; 
    qDebug() << "Time: " << stop_time; 

    stop_time = 0; 
    timer->stop(); 
} 

void pictures::clearPictures() 
{ 
    scene->deleteLater(); 
    images.clear(); 
    loadPics(); 
    ui->pushButtonStop->setEnabled(true); 
    ui->pushButtonNext->setEnabled(false); 
    timer->start(10); 
    timerImageChange->start(imageChangeTime); 
} 

void pictures::changeImageGrey() 
{ 
    timerGrey->start(greyTime); 
    timerImageChange->stop(); 
    image_counter = (image_counter+1)%4; 

    //scene_grey->removeItem(scene_grey->items().at(0)); 
    //scene_grey->addItem(images[image_counter]); 

    scene->removeItem(scene->items().at(0)); 
    scene->addItem(images[image_counter]); 



    /*int maximum = item1->boundingRect().width() > item1->boundingRect().height() ? item1->boundingRect().width() : item1->boundingRect().height(); 
    int dimension_width = ui->graphicsView->rect().width(); 
    int dimension_height = ui->graphicsView->rect().height(); 

    int biggest_canvas_dimension = dimension_width > dimension_height ? dimension_width : dimension_height; 

    if(maximum > ui->graphicsView->rect().width() || maximum > ui->graphicsView->rect().height()) 
    { 
     dimension_width = (int) (item1->boundingRect().width() * ((float)(biggest_canvas_dimension)/maximum)); 
     dimension_height = (int) (item1->boundingRect().height() * ((float)(biggest_canvas_dimension)/maximum)); 
     item1->setPixmap(item1->pixmap().scaled(dimension_width,dimension_height)); 
    }*/ 
    //scene->setSceneRect(ui->graphicsView->rect()); 

    //ui->graphicsView->setScene(scene_grey); 

} 

void pictures::changeImage() 
{ 
    timerImageChange->start(imageChangeTime); 
    timerGrey->stop(); 
    image_counter = (image_counter+1)%4; 

    qDebug() << " item1 = images[" + QString::number(image_counter) + "]"; 

    scene->removeItem(scene->items().at(0)); 

    item1 = images[image_counter]; 

    //qDebug() << QDir::toNativeSeparators((QDir::current().absolutePath() + QDir::separator() + "debug" + QDir::separator() + "pics" + QDir::separator() + QString::number(counter) + QDir::separator()+ QString::number(image_counter+1) +".jpg")); 


    int maximum = item1->boundingRect().width() > item1->boundingRect().height() ? item1->boundingRect().width() : item1->boundingRect().height(); 
    int dimension_width = ui->graphicsView->rect().width(); 
    int dimension_height = ui->graphicsView->rect().height(); 

    int biggest_canvas_dimension = dimension_width > dimension_height ? dimension_width : dimension_height; 

    if(maximum > ui->graphicsView->rect().width() || maximum > ui->graphicsView->rect().height()) 
    { 
     dimension_width = (int) (item1->boundingRect().width() * ((float)(biggest_canvas_dimension)/maximum)); 
     dimension_height = (int) (item1->boundingRect().height() * ((float)(biggest_canvas_dimension)/maximum)); 
     item1->setPixmap(item1->pixmap().scaled(dimension_width,dimension_height)); 
    } 

    //item1->setPixmap(item1->pixmap().scaled(QSize(ui->graphicsView->rect().width(), ui->graphicsView->rect().height()))); 
    //scene->setSceneRect(ui->graphicsView->rect()); 
    scene->addItem(item1); 
    //ui->graphicsView->setScene(scene); 

    //ui->graphicsView->setScene(scene); 
    //ui->graphicsView->adjustSize(); 

    //ui->graphicsView->show(); 

} 

回答

3

請記住,如果你的顯示器的刷新率爲60Hz,那麼每個圖像在16毫秒重繪一次。您無法以30 ms的精確時間進行繪圖,只能以16.666 ms的間隔進行計時。至少在Windows中,您無法輕易發現顯示器中顯示的圖像何時發生變化。例如,如果您的代碼顯示10毫秒的圖像,則您可以看到圖像或不顯示圖像。如果您顯示圖像的時間爲25毫秒,您可以看到圖像一次(16.666毫秒)或兩次(33.333毫秒)。

如果你真的想要確切的時間,我會建議使用OpenGL,你可以使用顯示器的垂直同步信息來繪製時間圖。

您在繪圖期間看到的線條可能是tearing。您也可以通過使用顯示器的垂直同步信息來擺脫這種情況。

您也正在使用Qt的計時器計數10毫秒的間隔。這是行不通的。超時至少爲10毫秒,但不能保證精確到10毫秒。實際上它更多,所以100次超時的總時間大概是1100毫秒左右。甚至更多,取決於您的操作系統。在Windows中,默認的定時器分辨率是16毫秒。然後100個超時加起來大約1700毫秒。您可以使用timeBeginPeriod更改計時器分辨率。

要獲得更準確的計時,請在要等待的時間段啓動計時器。如果您希望在70 ms後執行某些操作,請將計時器間隔更改爲70 ms,而不是進行7個10 ms超時。

+0

我第二次Roku的見解。一般來說,您可能希望使用'QElapsedTimer'來檢查從某個引用開始真正傳遞了多少時間,並且按照實時通過而不假設計時器事件可能已經觸發的時間。設置定時器在你想要的時候觸發,但是在timerEvent或者你的插槽裏面,根據實時的距離選擇顯示的東西。 –

+1

我現在使用16秒intervalls,因爲它似乎更準確。現在美麗但少工作:P。我試圖QGLWidget作爲視口(添加到pro文件中的opengl),以避免撕裂似乎是問題。感謝您的幫助 :) – user1439712