Qt — есть ли способ просмотреть QImage в реальном времени в пользовательском интерфейсе?

Я изучаю Qt и столкнулся с проблемой, которую не могу понять, поэтому я хотел бы спросить экспертов!

Я работаю над приложением, в котором я хотел бы иметь объект QImage (используя формат QImage::Format_RGB888) и иметь возможность манипулировать отдельными пикселями с помощью метода setPixel() и сохранять изображения с помощью QImageWriter... до сих пор, очень хорошо. Это все работает.

Мой способ показать этот Qimage заключается в том, что QMainWIndow содержит объект QGraphicsView, и я создал QGraphicsScene и установил эту сцену в свой GraphicsView MainWindow.

Проблема в том, что я хотел бы иметь возможность показывать этот QImage в пользовательском интерфейсе «вживую», чтобы пользователь мог видеть, как меняются пиксели, когда ими манипулируют. В настоящее время мне приходится повторно генерировать QGraphicsPixmapItem из изображения и повторно добавлятьPixmap() в сцену каждый раз, когда я хочу увидеть новые изменения.

Есть ли способ просмотреть QImage в реальном времени, чтобы сразу же увидеть внесенные изменения? Использую ли я неправильные объекты для хранения и/или отображения своего изображения?

У меня есть простой пример (только часть mainwindow.cpp... остальные файлы просто по умолчанию). В этом пользовательском интерфейсе есть только кнопка (для запуска изменений QImage) и место для отображения QImage на экране.

Я искал в Интернете, но не наткнулся на какие-либо сообщения, которые кажутся релевантными. Если у кого-то есть какие-либо предложения, я был бы рад услышать их! Благодарность,

-Эрик

QGraphicsScene *scene = NULL;
QGraphicsItem *line = NULL;
QImage *image = NULL;
QGraphicsPixmapItem *item = NULL;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    scene = new QGraphicsScene();
    image = new QImage(60, 60, QImage::Format_RGB888 );

    image->fill(Qt::cyan);

    ui->retranslateUi(this);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();

    line = (QGraphicsItem*) scene->addLine( QLine( 20, 40, 300, 100 ),
                    QPen(Qt::red, 6, Qt::DashLine, Qt::FlatCap));
    scene->setBackgroundBrush(QBrush(Qt::green, Qt::SolidPattern));
    scene->addEllipse(40, 80, 300, 240,
                        QPen(Qt::blue, 10, Qt::DashDotDotLine, Qt::RoundCap));

    item = new QGraphicsPixmapItem(QPixmap::fromImage(*image));
    scene->addPixmap(item->pixmap());

    // Connect the pushbutton to the buttonPressed method, below.
    connect(    ui->pushButton, SIGNAL(pressed()),
                this, SLOT( buttonPressed() ) );
}

// Slot connected to the button being pressed.
// Manipulate some pixels, and show the results.
void MainWindow::buttonPressed()
{
    printf("Now in buttonPressed...\n");
    int x, y;
    int offset = qrand();
    QRgb px;

    px = qRgb(20+offset, 10-offset, 30+offset);

    for (x=0; x< 60; x++)
        for(y=0; y< 60; y++)
        {
            image->setPixel(x, y, px );
        }
    // I'd like to NOT have to re-convert the image every time.
    item = new QGraphicsPixmapItem(QPixmap::fromImage(*image));
    scene->addPixmap(item->pixmap());
}

person user1524761    schedule 14.07.2012    source источник


Ответы (2)


Вы можете просто рисовать на QLabel напрямую, создавая растровое изображение на месте с помощью Qpixmap::fromImage

В качестве альтернативы вы можете сделать свой виджет отображения изображения onw, производным от QWidget и перегрузив событие рисования

void DisplayWidget::paintEvent(QPaintEvent*)
{

  QPainter p(this);
  p.drawImage(m_image); // you can also specfy a src and dest rect to zoom
}   
person Martin Beckett    schedule 14.07.2012
comment
Привет, Мартин, спасибо, что посмотрел это. Я все еще изучаю Qt, но я попробую эти предложения. Мне нужно получить доступ к отдельным пикселям, а у QPixmap нет функций доступа, которые позволяют это (если я что-то не упустил) - person user1524761; 17.07.2012

Я думаю, что лучшим способом будет сделать Qgraphicsitem производным от QGraphicsItem для вашего изображения и добавить этот элемент один раз в конструктор Mainwindow.

scene->addItem(Myimageitem);

Таким образом, вам не нужно делать это после каждой итерации, и всякий раз, когда вызывается обновление, ваше изображение будет автоматически обновляться.

person TopGun    schedule 17.07.2012
comment
Привет, TopGun, спасибо за это предложение... Я рассмотрю это! - person user1524761; 19.07.2012