Page 2 of 2 FirstFirst 12
Results 21 to 25 of 25

Thread: Getting an image from mysql database (as BLOB field) through subclassed QSqlQueryMode

  1. #21
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Getting an image from mysql database (as BLOB field) through subclassed QSqlQuery

    I am not sure what you are trying to do right now.

    Why all that code in the case for ueImageRole?
    Why not return the image Id as previously discussed?
    Are you attempting a different approach?

    Cheers,
    _

  2. #22
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Question Re: Getting an image from mysql database (as BLOB field) through subclassed QSqlQuery

    I've finally managed to get rid of the bug. Here is updated code:
    Qt Code:
    1. #ifndef UEPEOPLEMODEL_H
    2. #define UEPEOPLEMODEL_H
    3.  
    4. #include <QImage>
    5. #include <QVariant>
    6. #include <QStringList>
    7. #include <QDebug>
    8. #include <QHash>
    9. #include <QByteArray>
    10. #include <QSqlError>
    11. #include <QSqlQueryModel>
    12. #include <QSqlRecord>
    13. #include <QModelIndex>
    14. #include <QQuickImageProvider>
    15. #include <QByteArray>
    16. #include <QSqlRecord>
    17. #include <QDebug>
    18. #include <QSqlQuery>
    19.  
    20. #include "../settings/uedefaults.h"
    21. #include "../settings/uetypes.h"
    22.  
    23. class UePeopleModel : public QSqlQueryModel,
    24. public QQuickImageProvider
    25. {
    26. Q_OBJECT
    27.  
    28. private:
    29. QSqlDatabase m_ueDb;
    30.  
    31. private:
    32. QSqlDatabase ueDatabase() const
    33. { return this->m_ueDb; }
    34. void ueSetDatabase(const QSqlDatabase& database)
    35. { this->m_ueDb=database; }
    36. QImage ueImage(const QString& id) const;
    37.  
    38. public:
    39. UePeopleModel(QObject *parent=0);
    40. ~UePeopleModel();
    41.  
    42. QVariant data(const QModelIndex &index,
    43. int role) const Q_DECL_OVERRIDE;
    44. QImage requestImage(const QString &id,
    45. QSize *size,
    46. const QSize &requestedSize);
    47. UeTypeRoles roleNames() const;
    48.  
    49. public:
    50. static const int ueRoleName=Qt::UserRole+1;
    51. static const int ueRoleImage=Qt::UserRole+2;
    52. static const int ueRolePassword=Qt::UserRole+3;
    53. };
    54.  
    55. #endif // UEPEOPLEMODEL_H
    To copy to clipboard, switch view to plain text mode 
    and implementation:
    Qt Code:
    1. #include "uepeoplemodel.h"
    2.  
    3. UePeopleModel::UePeopleModel(QObject* parent)
    4. : QSqlQueryModel(parent),
    5. QQuickImageProvider(QQmlImageProviderBase::Image,
    6. QQmlImageProviderBase::ForceAsynchronousImageLoading)
    7. {
    8. if(!QSqlDatabase::connectionNames().contains(UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE,
    9. Qt::CaseInsensitive))
    10. {
    11. this->ueSetDatabase(QSqlDatabase::addDatabase(UePosDatabase::DATABASE_DRIVER,
    12. UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE));
    13. } // if
    14.  
    15. this->ueDatabase().setHostName(/*this->uePosSettings()->ueDbHostname()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
    16. this->ueDatabase().setDatabaseName(/*this->uePosSettings()->ueDbName()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
    17. this->ueDatabase().setUserName(/*this->uePosSettings()->ueDbUser()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
    18. this->ueDatabase().setPassword(/*this->uePosSettings()->ueDbPassword()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);
    19.  
    20. if(this->ueDatabase().open())
    21. {
    22. this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
    23. this->ueDatabase());
    24. if(this->lastError().isValid())
    25. qDebug() << this->lastError();
    26. }
    27. else
    28. {
    29. qDebug() << this->ueDatabase().lastError();
    30. }
    31.  
    32. qDebug() << this->ueDatabase().connectionNames();
    33. } // default constructor
    34.  
    35. UePeopleModel::~UePeopleModel()
    36. {
    37. } // default destructor
    38.  
    39. QVariant UePeopleModel::data(const QModelIndex &index,
    40. int role) const
    41. {
    42. switch(role)
    43. {
    44. case ueRoleImage:
    45. {
    46. //qDebug() << this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray().size();
    47.  
    48. return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray();
    49. } break; // case
    50.  
    51. case ueRoleName:
    52. {
    53. //qDebug() << this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
    54.  
    55. return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
    56. } break; // case
    57.  
    58. case ueRolePassword:
    59. {
    60. //qDebug() << this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD).toString();
    61.  
    62. return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD).toString();
    63. } break; // case
    64.  
    65. default:
    66. {
    67. return QSqlQueryModel::data(index,
    68. role);
    69. } break; // default
    70. } // switch
    71.  
    72. return QVariant();
    73. } // data
    74.  
    75. QImage UePeopleModel::ueImage(const QString &id) const
    76. {
    77. qDebug() << this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray().size();
    78.  
    79. return QImage::fromData(this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray(),
    80. "PNG");
    81. } // image
    82.  
    83. QImage UePeopleModel::requestImage(const QString &id,
    84. QSize *size,
    85. const QSize &requestedSize)
    86. {
    87. if(size)
    88. {
    89. *size=QSize(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
    90. UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT);
    91. } // if
    92.  
    93. QImage image(requestedSize.width()>0?requestedSize.width():UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
    94. requestedSize.height()>0?requestedSize.height():UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT,
    95. QImage::Format_ARGB32);
    96.  
    97. image=this->ueImage(id);
    98. image=image.scaled(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
    99. UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT,
    100. Qt::IgnoreAspectRatio,
    101. Qt::SmoothTransformation);
    102.  
    103. return image;
    104. } // requestImage
    105.  
    106. UeTypeRoles UePeopleModel::roleNames() const
    107. {
    108. UeTypeRoles roles;
    109.  
    110. const int iRoleName=UePeopleModel::ueRoleName;
    111. const int iRoleImage=UePeopleModel::ueRoleImage;
    112. const int iRolePassword=UePeopleModel::ueRolePassword;
    113.  
    114. roles.insert(iRoleName,
    115. "ueRoleName");
    116. roles.insert(iRoleImage,
    117. "ueRoleImage");
    118. roles.insert(iRolePassword,
    119. "ueRolePassword");
    120.  
    121. return roles;
    122. } // roleNames
    To copy to clipboard, switch view to plain text mode 
    In the UePeopleModel::data() method, break statements were placed wrong and inside default statement now I do master's class
    Qt Code:
    1. return QSqlQueryModel::data(index,
    2. role);
    To copy to clipboard, switch view to plain text mode 
    But now I have a new problem:
    My UePeopleModel fetches users from database (for now: Name, Image and Password). Names and password are fetch ok, but qml shows for every user my Image (which is first fetched. In UePeopleModel::data() method images are fetched correctly (I've done qDebug() of image sizes and compared with images in database). Here is screenshot:
    QMLItemsOnlyFirstImageDisplayed.png
    Why is QML showing only first image fetched from db?
    Qt 5.3 Opensource & Creator 3.1.2

  3. #23
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Getting an image from mysql database (as BLOB field) through subclassed QSqlQuery

    Your data() method does not return an id for the image, but the image data itself.
    I've already asked you before why you changed that.

    If you don't return an id that contains the row number, then the id you get in image() is also not a row number.
    So id.toInt() returns 0.

    Also in your requestImage() method, why do you set "size" to a fixed value but then used requestedSize?
    Set "size" at the end, when you actually know which size you returned.

    Also, why create an image an immediately discard it?
    Creating and deleting an image buffer are not cheap operations (heap memory allocations).

    So

    1) Fix data() so that it returns an id for the image again (and maybe thing about why you changed to to something that does not work without any need of doing so)
    2) in requestImage() set "size" at the end, from the size() vaule of the "image"
    3) Do not create an empty image that you then don't need (lines 93-95), the image() method returns the image that you need.

    Cheers,
    _

  4. The following user says thank you to anda_skoa for this useful post:

    MarkoSan (3rd September 2015)

  5. #24
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Getting an image from mysql database (as BLOB field) through subclassed QSqlQuery

    Ok, is this better (I think it is because now works! )?
    UePeopleModel implementation:
    Qt Code:
    1. #include "uepeoplemodel.h"
    2.  
    3. UePeopleModel::UePeopleModel(QObject* parent)
    4. : QSqlQueryModel(parent),
    5. QQuickImageProvider(QQmlImageProviderBase::Image,
    6. QQmlImageProviderBase::ForceAsynchronousImageLoading)
    7. {
    8. if(!QSqlDatabase::connectionNames().contains(UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE,
    9. Qt::CaseInsensitive))
    10. {
    11. this->ueSetDatabase(QSqlDatabase::addDatabase(UePosDatabase::DATABASE_DRIVER,
    12. UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE));
    13. } // if
    14.  
    15. this->ueDatabase().setHostName(/*this->uePosSettings()->ueDbHostname()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
    16. this->ueDatabase().setDatabaseName(/*this->uePosSettings()->ueDbName()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
    17. this->ueDatabase().setUserName(/*this->uePosSettings()->ueDbUser()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
    18. this->ueDatabase().setPassword(/*this->uePosSettings()->ueDbPassword()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);
    19.  
    20. if(this->ueDatabase().open())
    21. {
    22. this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
    23. this->ueDatabase());
    24. if(this->lastError().isValid())
    25. qDebug() << this->lastError();
    26. }
    27. else
    28. {
    29. qDebug() << this->ueDatabase().lastError();
    30. }
    31.  
    32. // qDebug() << this->ueDatabase().connectionNames();
    33. } // default constructor
    34.  
    35. UePeopleModel::~UePeopleModel()
    36. {
    37. } // default destructor
    38.  
    39. QVariant UePeopleModel::data(const QModelIndex &index,
    40. int role) const
    41. {
    42. switch(role)
    43. {
    44. case ueRoleImage:
    45. {
    46. //return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray();
    47. return QString::number(index.row());
    48. } break; // case
    49.  
    50. case ueRoleName:
    51. {
    52. return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
    53. } break; // case
    54.  
    55. case ueRolePassword:
    56. {
    57. return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD).toString();
    58. } break; // case
    59.  
    60. default:
    61. {
    62. return QSqlQueryModel::data(index,
    63. role);
    64. } break; // default
    65. } // switch
    66.  
    67. return QVariant();
    68. } // data
    69.  
    70. QImage UePeopleModel::ueImage(const QString &id) const
    71. {
    72. return QImage::fromData(this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray(),
    73. "PNG").scaled(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
    74. UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT,
    75. Qt::IgnoreAspectRatio,
    76. Qt::SmoothTransformation);
    77. } // image
    78.  
    79. QImage UePeopleModel::requestImage(const QString &id,
    80. QSize *size,
    81. const QSize &requestedSize)
    82. {
    83. Q_UNUSED(requestedSize);
    84.  
    85. if(size)
    86. {
    87. *size=QSize(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
    88. UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT);
    89. } // if
    90.  
    91. return this->ueImage(id);
    92. } // requestImage
    93.  
    94. UeTypeRoles UePeopleModel::roleNames() const
    95. {
    96. UeTypeRoles roles;
    97.  
    98. const int iRoleName=UePeopleModel::ueRoleName;
    99. const int iRoleImage=UePeopleModel::ueRoleImage;
    100. const int iRolePassword=UePeopleModel::ueRolePassword;
    101.  
    102. roles.insert(iRoleName,
    103. "ueRoleName");
    104. roles.insert(iRoleImage,
    105. "ueRoleImage");
    106. roles.insert(iRolePassword,
    107. "ueRolePassword");
    108.  
    109. return roles;
    110. } // roleNames
    To copy to clipboard, switch view to plain text mode 
    Now, I still do not understand something:
    In method QImage UePeopleModel::requestImage(const QString &id, QSize *size, const QSize &requestedSize):
    Qt Code:
    1. QImage UePeopleModel::ueImage(const QString &id) const
    2. {
    3. return QImage::fromData(this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray(),
    4. "PNG").scaled(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
    5. UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT,
    6. Qt::IgnoreAspectRatio,
    7. Qt::SmoothTransformation);
    8. } // image
    9.  
    10. QImage UePeopleModel::requestImage(const QString &id,
    11. QSize *size,
    12. const QSize &requestedSize)
    13. {
    14. Q_UNUSED(requestedSize);
    15.  
    16. if(size)
    17. {
    18. *size=QSize(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
    19. UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT);
    20. } // if
    21.  
    22. return this->ueImage(id);
    23. } // requestImage
    To copy to clipboard, switch view to plain text mode 
    How do I use requestedSize in QImage UePeopleModel::requestImage(const QString &id, QSize *size, const QSize &requestedSize) since I already get now scaled image from method QImage UePeopleModel::ueImage(const QString &id) const?
    Qt 5.3 Opensource & Creator 3.1.2

  6. #25
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Getting an image from mysql database (as BLOB field) through subclassed QSqlQuery

    Quote Originally Posted by MarkoSan View Post
    Ok, is this better (I think it is because now works! )?
    Yes, data() looks good now.

    Quote Originally Posted by MarkoSan View Post
    Now, I still do not understand something:
    In method QImage UePeopleModel::requestImage(const QString &id, QSize *size, const QSize &requestedSize):
    How do I use requestedSize in QImage UePeopleModel::requestImage(const QString &id, QSize *size, const QSize &requestedSize) since I already get now scaled image from method QImage UePeopleModel::ueImage(const QString &id) const?
    Just remove the image() method and do its code inside requestImage().

    The initial suggestion for image() was based on the idea of a separate image provider object.
    Since your class is now a model and the image provider in one, this is no longer necessary.

    Alternatively, pass the requestedSize as an additional argument to image().

    Cheers,
    _

  7. The following user says thank you to anda_skoa for this useful post:

    MarkoSan (4th September 2015)

Similar Threads

  1. Replies: 4
    Last Post: 16th June 2011, 15:49
  2. Read BLOB from MySQL database
    By zero-n in forum Newbie
    Replies: 3
    Last Post: 22nd May 2011, 20:59
  3. How to update BLOB field in a SQLite database ?
    By aircraftstories in forum Qt Programming
    Replies: 6
    Last Post: 8th April 2011, 21:45
  4. Replies: 2
    Last Post: 17th February 2010, 15:32
  5. Replies: 1
    Last Post: 14th September 2009, 09:48

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.