Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: sendevent от Июнь 17, 2010, 22:23



Название: ToolTip + raw image [РЕШЕНО]
Отправлено: sendevent от Июнь 17, 2010, 22:23
есть QPixmap - некий сграбленный виджет, надо добавить его в тултип.
Код:
//-- QTDIR/examples/desktop/screenshot/screenshot.cpp/#192
void Screenshot::updateScreenshotLabel()
{
    screenshotLabel->setPixmap(originalPixmap.scaled(screenshotLabel->size(),
                                                     Qt::KeepAspectRatio,
                                                     Qt::SmoothTransformation));
    
    const QPixmap *pixmap = screenshotLabel->pixmap();
    
    if( pixmap && !pixmap->isNull() )
    {
        QString imgSrcTmpl = QString( "<img src=\"%3\" width=%1 height=%2>" )
                .arg( pixmap->width() )
                .arg( pixmap->height() )
                .arg( "%1" );
        QString strToolTip;
        QString tmpFileName( "./test.png" );
        if( pixmap->save( tmpFileName, "PNG" ) )
        {
            QString str( "image (file path):<br>%1<br>" );
            strToolTip.append( str.arg( imgSrcTmpl.arg( tmpFileName ) ) );
        }
        
        QBuffer imageBuffer;
        if (imageBuffer.open(QBuffer::ReadWrite) && pixmap->save(&imageBuffer, "PNG"))
        {
            QString str( "image (base64):<br>%1<br>" );
            strToolTip.append( str.arg(
                imgSrcTmpl.arg( "data:image/png;base64,"
                +QLatin1String( imageBuffer.buffer().toBase64() ) ) ) );
        }
        
        screenshotLabel->setToolTip( strToolTip );
    }
}

<img src="/file/or/resources/path"> - работает замечательно, а вот <img src="data:image/png;base64,..." - вставляет "blank-image":

(http://img22.imageshack.us/img22/7914/67348282.th.png) (http://img22.imageshack.us/img22/7914/67348282.png)

можно "сохранить на винт и добавить" - но не хотелось бы, по крайней мере пока не станет ясно, что другого пути нет. (т.к. количество одновременно валидных "скриншотов" не фиксировано, прийдется либо гадить в tmp временными файлами, либо в ручную обеспечивать уникальность имен и обрадовать инсталлятор новой "подопечной" директорией).

есть идеи?


Название: Re: ToolTip + raw image
Отправлено: GreatSnake от Июнь 18, 2010, 13:34
Есть большое подозрение, что для рендеринга RichText-a в Qt используется усечённая версия html, в котором такие навороты не поддерживаются.
Могу предложить hack как это обойти:

Код
C++ (Qt)
void registerPixmap( const QPixmap& pm, const QString& name )
{
QFileInfo info;
QString key = QString( "qt_pixmap_:%1_%2_0_0" ).arg( name ).
arg( QString::number( info.lastModified().toTime_t() ) );
QPixmapCache::insert( key, pm );
}
 
void Screenshot::updateScreenshotLabel()
{
. . .
registerPixmap( *screenshotLabel->pixmap(), "test" );
screenshotLabel->setToolTip( "<img src=':test'>" );   // перед именем файла обязательно вставить ':', чтобы Qt искала в своих ресурсах.
. . .
}
 
 
Правда в RichText-e я это не пробовал, но по идее должно прокатить.


Название: Re: ToolTip + raw image
Отправлено: sendevent от Июнь 18, 2010, 14:04
woo-hoo!
то, что надо, под уиндоуз по крайней мере, остальное потом проверю.
(тока "<img src='test'>" - без двоеточия перед именем).
спасибо огромное!

upd:
поторопился, такой финт тоже не проходит :-(
с толку сбил "test.png", оставшийся в "./" от предыдущих экспериментов - атрибут src в теге img подхватывал именно его, а не ключ в кеше, и изображение из файла выводилось нормально.


Название: Re: ToolTip + raw image
Отправлено: shadone от Июнь 21, 2010, 11:19
возможно получится зарегистрировать картинку в виде ресурса - QResouce::registerResouce(imageadata, "foo.png") и потом использовать этот путьв тултипе


Название: Re: ToolTip + raw image
Отправлено: ритт от Июнь 21, 2010, 12:06
уже как минимум второй раз вижу человека, заинтересованного в подобном функционале...пора бы добавить уже фичу :)


Название: Re: ToolTip + raw image
Отправлено: GreatSnake от Июнь 21, 2010, 12:19
Да, действительно не прокатывает.
Дело в том, что QToolTip отнаследован от QLabel, который в свою очередь для отрисовки RichText-a использует QTextDocument.
А у QTextDocument есть virtual QVariant loadResource( int type, const QUrl& name ), используя который можно грузить что угодно и откуда угодно.
Только вот тролли всё это от нас спрятали. :(
Есть 2 варианта: написать свой QToolTip, что в принципе несложно, либо воспользоваться приватными методами,
которые нам тролли "любезно" предоставили:

Код
C++ (Qt)
#include <QPixmapCache>
#include <private/qtextimagehandler_p.h>
 
static QImage richTextImageLoader( const QString& name, const QString &context )
{
QImage img;
QPixmap pix;
 
if( QPixmapCache::find( name, pix ) )
return pix.toImage();
 
return QImage();
}
 
void Screenshot::updateScreenshotLabel()
{
. . .
static bool init;
if( !init++ )
   QTextImageHandler::externalLoader = richTextImageLoader;
 
QPixmapCache::insert( "test", *screenshotLabel->pixmap() );
screenshotLabel->setToolTip( "<img src='test'>" );
. . .
}
 

На сей раз я этот код проверил - всё работает)


Название: Re: ToolTip + raw image
Отправлено: SABROG от Июнь 21, 2010, 15:17
возможно получится зарегистрировать картинку в виде ресурса - QResouce::registerResouce(imageadata, "foo.png") и потом использовать этот путьв тултипе

Нет. rccData указывает на данные в определенном формате, который генерит утилита rcc. Библиотеки Qt не содержат классов, которые могут генерить файлы в этом формате.

Другой вариант, использовать QAbstractFileEngine и реализовать "доставку" данных (картинки), к примеру, для собственной "файловой системы". На QtCentre были исходники memfilehandler.


Название: Re: ToolTip + raw image
Отправлено: sendevent от Июнь 25, 2010, 14:17
Другой вариант, использовать QAbstractFileEngine и реализовать "доставку" данных (картинки), к примеру, для собственной "файловой системы". На QtCentre были исходники memfilehandler.
оно!
хотя сначала показалось что как-то многовато действий для, казалось бы, простейшей задачи, решение действительно довольно несложное и удобное.
пример прост до безобразия, глядя на него не проблема реализовать подобное с подсчетом ссылок на "файлы" и корректным расшариванием памяти внутри своего проекта.
всем спасибо!

ps: на qtcentr'е исходники в тар.гз, который под виндой не прожевали рар/зип, нормально распаковал тока 7z. на всяк случай прицепил тут в zip'е.