Page 1 of 2 12 LastLast
Results 1 to 20 of 25

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

  1. #1
    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 Getting an image from mysql database (as BLOB field) through subclassed QSqlQueryMode

    I am working on Qt/QML app, which connects to mysql database and fetches data from it. Now, how do I fetch image from database (as BLOB field) using QSqlQueryModel? Now, I know how to connect to database, I've written simple read only subclassed QSqlQueryModel, I do know how to get the value of some field, but how do I get image and show it in some QML ListView? Does anyone has some experience and/or example with QQuickImageProvider, is this right way to go?
    Qt 5.3 Opensource & Creator 3.1.2

  2. #2
    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 model needs to return some string id for each image when its data() method is called by the view.
    The view's delegate then needs to use that id to construct an "image://" URL.
    Your image provider then needs to convert the BLOB data for that id to a QImage.

    Cheers,
    _

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

    MarkoSan (14th August 2015)

  4. #3
    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

    Quote Originally Posted by anda_skoa View Post
    Your model needs to return some string id for each image when its data() method is called by the view.
    The view's delegate then needs to use that id to construct an "image://" URL.
    Your image provider then needs to convert the BLOB data for that id to a QImage.

    Cheers,
    _
    Can you please provide me some example?
    Qt 5.3 Opensource & Creator 3.1.2

  5. #4
    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

    Qt Code:
    1. QVariant MyModel::data(const QModelIndex & index, int role) const
    2. {
    3. if (role == ImageRole) {
    4. return QString::number(index.row());
    5. }
    6.  
    7. /// other data
    8. }
    9.  
    10. QImage MyModel::image(const QString &id) const
    11. {
    12. int row = id.toInt();
    13.  
    14. // load BLOB for image on row "row", return
    15. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. Image {
    2. source: "image://mysqlimageprovider/" * model.image
    3. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. QImage MyImageProvider::requestImage(const QString &d, QSize *size, const QSize &requestedSize, bool requestedAutoTransform)
    2. {
    3. QImage image = myModel->image(id);
    4. *size = image.size();
    5. return image;
    6. }
    To copy to clipboard, switch view to plain text mode 

    You could even inherit your model from both the current base class and QQuickImageProvider.

    Cheers,
    _

  6. #5
    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

    Quote Originally Posted by anda_skoa View Post
    Qt Code:
    1. QVariant MyModel::data(const QModelIndex & index, int role) const
    2. {
    3. if (role == ImageRole) {
    4. return QString::number(index.row());
    5. }
    6.  
    7. /// other data
    8. }
    9.  
    10. QImage MyModel::image(const QString &id) const
    11. {
    12. int row = id.toInt();
    13.  
    14. // load BLOB for image on row "row", return
    15. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. Image {
    2. source: "image://mysqlimageprovider/" * model.image
    3. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. QImage MyImageProvider::requestImage(const QString &d, QSize *size, const QSize &requestedSize, bool requestedAutoTransform)
    2. {
    3. QImage image = myModel->image(id);
    4. *size = image.size();
    5. return image;
    6. }
    To copy to clipboard, switch view to plain text mode 

    You could even inherit your model from both the current base class and QQuickImageProvider.

    Cheers,
    _
    Wow, superb idea! Will try asap!
    Qt 5.3 Opensource & Creator 3.1.2

  7. #6
    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

    Hmm, it seems I've forgot a little about Qt models, here is my code, first header file:
    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 <QtSql/QSqlError>
    11. #include <QtSql/QSqlQueryModel>
    12. #include <QtSql/QSqlRecord>
    13. #include <QModelIndex>
    14. #include <QQuickImageProvider>
    15.  
    16. #include "../settings/uedefaults.h"
    17.  
    18. class UePeopleModel : public QSqlQueryModel, QQuickImageProvider
    19. {
    20. Q_OBJECT
    21.  
    22. /*
    23. private:
    24.   QHash<int, QByteArray> m_ueRoleNames;
    25.  
    26.   void ueGenerateRoleNames();
    27. */
    28.  
    29. public:
    30. UePeopleModel(QObject *parent=0);
    31. ~UePeopleModel();
    32.  
    33. QVariant data(const QModelIndex &index,
    34. int role) const Q_DECL_OVERRIDE;
    35. // void ueRefresh();
    36. /*
    37.   inline QHash<int, QByteArray> roleNames() const
    38.   { return this->m_ueRoleNames; }
    39. */
    40.  
    41. public:
    42. static const int UePersonNameRole=Qt::UserRole+1;
    43. static const int UePersonImageRole=UePersonNameRole+1;
    44. };
    45.  
    46. #endif // UEPEOPLEMODEL_H
    To copy to clipboard, switch view to plain text mode 
    and its implementation:
    Qt Code:
    1. #include "uepeoplemodel.h"
    2.  
    3. UePeopleModel::UePeopleModel(QObject* parent)
    4. : QSqlQueryModel(parent),
    5. QQuickImageProvider(QQmlImageProviderBase::Image,
    6. 0)
    7. {
    8.  
    9. if(!QSqlDatabase::connectionNames().contains(UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE,
    10. Qt::CaseInsensitive))
    11. {
    12. db=QSqlDatabase::addDatabase(UePosDatabase::DATABASE_DRIVER,
    13. UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE);
    14. } // if
    15.  
    16. db.setHostName(/*this->uePosSettings()->ueDbHostname()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
    17. db.setDatabaseName(/*this->uePosSettings()->ueDbName()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
    18. db.setUserName(/*this->uePosSettings()->ueDbUser()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
    19. db.setPassword(/*this->uePosSettings()->ueDbPassword()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);
    20.  
    21. if(db.open())
    22. {
    23. this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
    24. db);
    25. //this->ueGenerateRoleNames();
    26. }
    27. else
    28. {
    29. qDebug() << db.lastError().text();
    30. }
    31. } // default constructor
    32.  
    33. UePeopleModel::~UePeopleModel()
    34. {
    35. } // default destructor
    36.  
    37. QVariant UePeopleModel::data(const QModelIndex &index,
    38. int role) const
    39. {
    40. // QVariant value;
    41.  
    42. // if(role<Qt::UserRole)
    43. // {
    44. // value=QSqlQueryModel::data(index,
    45. // role);
    46. // }
    47. // else
    48. // {
    49. // int iColumnIndex=role-Qt::UserRole-1;
    50. // QModelIndex modelIndex=this->index(index.row(),
    51. // iColumnIndex);
    52.  
    53. // value=QSqlQueryModel::data(modelIndex,
    54. // Qt::DisplayRole);
    55. // } // if
    56.  
    57. // return value;
    58.  
    59. QVariant value=QSqlQueryModel::data(index,
    60. role);
    61.  
    62. if(value.isValid()&&role==Qt::DisplayRole)
    63. {
    64. switch(index.column())
    65. {
    66. case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_ID:
    67. return value.toInt();
    68.  
    69. case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME:
    70. return value.toString();
    71.  
    72. case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD:
    73. return value.toString();
    74.  
    75. case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_CARD:
    76. return value.toString();
    77.  
    78. case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE:
    79. {
    80. QImage image;
    81.  
    82. image.loadFromData(value.toByteArray());
    83.  
    84. return image;
    85. } // case
    86.  
    87. default:
    88. return value;
    89. } // switch
    90. } // if
    91.  
    92. return QVariant();
    93. } // data
    94.  
    95. /*
    96. void UePeopleModel::ueRefresh()
    97. {
    98.   this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE);
    99. } // ueRefresh
    100. */
    101.  
    102. //void UePeopleModel::ueGenerateRoleNames()
    103. //{
    104. // //this->roleNames().clear();
    105. // m_ueRoleNames.clear();
    106. // for(int iIndex=0; iIndex<this->record().count(); iIndex++)
    107. // {
    108. ///*
    109. // this->roleNames().insert(Qt::UserRole+1+iIndex,
    110. // this->record().fieldName(iIndex).toUtf8());
    111. //*/
    112. // m_ueRoleNames.insert(Qt::UserRole+1+iIndex,
    113. // this->record().fieldName(iIndex).toUtf8());
    114. // } // for
    115. //} // ueGenerateRoleNames
    To copy to clipboard, switch view to plain text mode 
    Am I using Qt:isplayRole in right way or should I implement custom roles? And how do I then use this data()method in qml?
    Qt 5.3 Opensource & Creator 3.1.2

  8. #7
    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

    You can use Qt:isplayRole, it is mapped by default to "model.display" in QML.

    However, you need to keep in mind that the QtQuick views, e.g. ListView or TableView, do not deal with model columns, only rows, so you will need custom roles anyway.

    I would suggest to use custom roles for all columns and not use Qt:isplayRole other than maybe for debugging (e.g. with a QWidget based table view).

    So in your data() method you first need to map the role to a column and then proceed with quering the data from the base class.

    Cheers,
    _

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

    MarkoSan (16th August 2015)

  10. #8
    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

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

    Ok, I am a little lost now. I've done this:
    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 <QtSql/QSqlError>
    11. #include <QtSql/QSqlQueryModel>
    12. #include <QtSql/QSqlRecord>
    13. #include <QModelIndex>
    14. #include <QQuickImageProvider>
    15.  
    16. #include "../settings/uedefaults.h"
    17.  
    18. class UePeopleModel : public QSqlQueryModel, QQuickImageProvider
    19. {
    20. Q_OBJECT
    21.  
    22. public:
    23. UePeopleModel(QObject *parent=0);
    24. ~UePeopleModel();
    25.  
    26. QVariant data(const QModelIndex &index,
    27. int role) const Q_DECL_OVERRIDE;
    28. QImage image(const QString &id) const;
    29. QImage requestImage(const QString &id,
    30. QSize *size,
    31. const QSize &requestedSize);
    32.  
    33. public:
    34. static const int UePersonNameRole=Qt::UserRole+1;
    35. static const int UePersonImageRole=UePersonNameRole+1;
    36. };
    37.  
    38. #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.  
    9. if(!QSqlDatabase::connectionNames().contains(UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE,
    10. Qt::CaseInsensitive))
    11. {
    12. db=QSqlDatabase::addDatabase(UePosDatabase::DATABASE_DRIVER,
    13. UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE);
    14. } // if
    15.  
    16. db.setHostName(/*this->uePosSettings()->ueDbHostname()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
    17. db.setDatabaseName(/*this->uePosSettings()->ueDbName()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
    18. db.setUserName(/*this->uePosSettings()->ueDbUser()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
    19. db.setPassword(/*this->uePosSettings()->ueDbPassword()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);
    20.  
    21. if(db.open())
    22. {
    23. this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
    24. db);
    25. //this->ueGenerateRoleNames();
    26. }
    27. else
    28. {
    29. qDebug() << db.lastError().text();
    30. }
    31. } // default constructor
    32.  
    33. UePeopleModel::~UePeopleModel()
    34. {
    35. } // default destructor
    36.  
    37. QVariant UePeopleModel::data(const QModelIndex &index,
    38. int role) const
    39. {
    40. QVariant value=QSqlQueryModel::data(index,
    41. role);
    42. if(value.isValid())
    43. {
    44. switch(role)
    45. {
    46. case UePeopleModel::UePersonNameRole:
    47. {
    48. return value.toString();
    49. } // case
    50.  
    51. case UePeopleModel::UePersonImageRole:
    52. {
    53. return QString::number(index.row());
    54. } // case
    55.  
    56. default:
    57. value=QVariant();
    58. } // switch
    59. } // if
    60.  
    61. return value;
    62. } // data
    63.  
    64. QImage UePeopleModel::image(const QString &id) const
    65. {
    66. int iRow=id.toInt();
    67. } // image
    68.  
    69. QImage UePeopleModel::requestImage(const QString &id,
    70. QSize *size,
    71. const QSize &requestedSize)
    72. {
    73. QImage image=this->image(id);
    74.  
    75. *size = image.size();
    76.  
    77. return image;
    78. } // requestImage
    To copy to clipboard, switch view to plain text mode 
    Now what?
    Qt 5.3 Opensource & Creator 3.1.2

  11. #9
    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

    Couple of things:

    - in order to be able to use this class as a QQuickImageProvider, it needs to have a "is-a" relation ship, i.e. publically inherit from QQuickImageProvider
    - in data() it doesn't make sense to use the role as given to query the base class, after all these roles will most often be your custom roles and have no meaning for the base class
    - you are missing the roleNames() override that returns the mapping of role names (used in QML) to role numbers (using in the C++ API).

    Cheers,
    _

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

    MarkoSan (20th August 2015)

  13. #10
    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

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

    Quote Originally Posted by anda_skoa View Post
    Couple of things:

    - in order to be able to use this class as a QQuickImageProvider, it needs to have a "is-a" relation ship, i.e. publically inherit from QQuickImageProvider
    - in data() it doesn't make sense to use the role as given to query the base class, after all these roles will most often be your custom roles and have no meaning for the base class
    - you are missing the roleNames() override that returns the mapping of role names (used in QML) to role numbers (using in the C++ API).

    Cheers,
    _
    Well, class is publicly inherited from QQuickImageProvider:
    Qt Code:
    1. class UePeopleModel : public QSqlQueryModel, QQuickImageProvider
    To copy to clipboard, switch view to plain text mode 
    I've upgraded function data(), is now ok:
    Qt Code:
    1. QVariant UePeopleModel::data(const QModelIndex &index,
    2. int role) const
    3. {
    4. QVariant value=QSqlQueryModel::data(index,
    5. role);
    6. if(value.isValid())
    7. {
    8. switch(role)
    9. {
    10. case ueRoleName:
    11. {
    12. return value.toString();
    13. } // case
    14.  
    15. case ueRoleImage:
    16. {
    17. return QString::number(index.row());
    18. } // case
    19.  
    20. default:
    21. value=QVariant();
    22. } // switch
    23. } // if
    24.  
    25. return value;
    26. } // data
    To copy to clipboard, switch view to plain text mode 
    But what do I have to put inside method UePeopleModel::image?

    Sincerely yours,
    Marko
    Qt 5.3 Opensource & Creator 3.1.2

  14. #11
    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
    Well, class is publicly inherited from QQuickImageProvider:
    Qt Code:
    1. class UePeopleModel : public QSqlQueryModel, QQuickImageProvider
    To copy to clipboard, switch view to plain text mode 
    Nope. Unless your code looks different in reality, this is a private inheritance

    Quote Originally Posted by MarkoSan View Post
    I've upgraded function data(), is now ok:
    Nope, see my last comment.

    Quote Originally Posted by MarkoSan View Post
    But what do I have to put inside method UePeopleModel::image?
    You get the BLOB from the base class for the given row and then load it into a QImage.
    If the BLOB is data in a format known to Qt, then you can probably use QImage::loadFromData().

    Cheers,
    _

  15. #12
    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

    Quote Originally Posted by anda_skoa View Post
    Nope. Unless your code looks different in reality, this is a private inheritance


    Nope, see my last comment.


    You get the BLOB from the base class for the given row and then load it into a QImage.
    If the BLOB is data in a format known to Qt, then you can probably use QImage::loadFromData().

    Cheers,
    _
    Do you have some example regarding this problem, particulary passing text and Image to qml, because I do not understand you regarding data() method?


    Added after 50 minutes:


    Ok, now I've upgraded method image:
    Qt Code:
    1. QImage UePeopleModel::image(const QString &id) const
    2. {
    3. return QImage::fromData(this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray(),
    4. "PNG");
    5. } // image
    To copy to clipboard, switch view to plain text mode 
    Is this ok now?
    Secondly, the header of class is now:
    Qt Code:
    1. class UePeopleModel : public QSqlQueryModel,
    2. public QQuickImageProvider
    To copy to clipboard, switch view to plain text mode 
    to get as-is relationship. Is this ok?
    I still do not know what is wrong with data() method:
    Qt Code:
    1. QVariant UePeopleModel::data(const QModelIndex &index,
    2. int role) const
    3. {
    4. QVariant value=QSqlQueryModel::data(index,
    5. role);
    6. if(value.isValid())
    7. {
    8. switch(role)
    9. {
    10. case ueRoleName:
    11. {
    12. return value.toString();
    13. } // case
    14.  
    15. case ueRoleImage:
    16. {
    17. return QString::number(index.row());
    18. } // case
    19.  
    20. default:
    21. value=QVariant();
    22. } // switch
    23. } // if
    24.  
    25. return value;
    26. } // data
    To copy to clipboard, switch view to plain text mode 
    Can someone please help me?!
    Last edited by MarkoSan; 20th August 2015 at 12:34.
    Qt 5.3 Opensource & Creator 3.1.2

  16. #13
    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

    You data() method is still wrong because you do not handle the role correctly.

    As I wrote before, the roles you have specified mean nothing to the data() method of the base class.
    So calling the base implementation with the arguments you are getting is not going to work at all.

    In comment #7 I explained that you need to map the roles used by you to the columns used by the base class.
    A QtQuick view will always call with column 0 and one of the roles you have specified and used by name.
    The base class implementation expects column value > 0 for fields other than the first and one of the Qt standard item roles.

    So you first need to switch() on the role to determine the column of the data you are supposed to deliver.
    Then call the base class' data() with that row/column and e.g. Qt:isplayRole.

    Unless of course the initial role is the image role, in which case you return the identifier that you later on can use to provide the image.

    Cheers,
    _

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

    MarkoSan (21st August 2015)

  18. #14
    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

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

    Quote Originally Posted by anda_skoa View Post
    You data() method is still wrong because you do not handle the role correctly.

    As I wrote before, the roles you have specified mean nothing to the data() method of the base class.
    So calling the base implementation with the arguments you are getting is not going to work at all.

    In comment #7 I explained that you need to map the roles used by you to the columns used by the base class.
    A QtQuick view will always call with column 0 and one of the roles you have specified and used by name.
    The base class implementation expects column value > 0 for fields other than the first and one of the Qt standard item roles.

    So you first need to switch() on the role to determine the column of the data you are supposed to deliver.
    Then call the base class' data() with that row/column and e.g. Qt:isplayRole.

    Unless of course the initial role is the image role, in which case you return the identifier that you later on can use to provide the image.

    Cheers,
    _
    Ok, will try, but where do I get identifier that I can later use to provide the image? And am I getting closer with data()method:
    Qt Code:
    1. QVariant UePeopleModel::data(const QModelIndex &index,
    2. int role) const
    3. {
    4. QVariant value=QVariant();
    5.  
    6. switch(role)
    7. {
    8. case UePeopleModel::ueRoleImage:
    9. {
    10. value=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toString();
    11. } // case
    12.  
    13. case UePeopleModel::ueRoleName:
    14. {
    15. value=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
    16. } // case
    17.  
    18. default:
    19. return value;
    20. } // switch
    21.  
    22. return value;
    23. } // data
    To copy to clipboard, switch view to plain text mode 
    Last edited by MarkoSan; 21st August 2015 at 08:32.
    Qt 5.3 Opensource & Creator 3.1.2

  19. #15
    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, will try, but where do I get identifier that I can later use to provide the image?
    I am not sure what you mean, we had that already several comments ago.
    The simplest way is to just encode the row as a string.


    Quote Originally Posted by MarkoSan View Post
    And am I getting closer with data()method:
    Yes, that looks better.
    Obviously the handling of the image role is wrong, but the name looks fine.
    You wouldn't need to call toString() though.

    Cheers,
    _

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

    MarkoSan (21st August 2015)

  21. #16
    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, now I am getting QML runtime errros:
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Cannot open: qrc:/gui/delegates/nan
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Cannot open: qrc:/gui/delegates/nan
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Cannot open: qrc:/gui/delegates/nan
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Cannot open: qrc:/gui/delegates/nan
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Cannot open: qrc:/gui/delegates/nan
    Here is QML ListView error is generated in:
    Qt Code:
    1. ListView
    2. {
    3. id: uePeopleListView
    4. boundsBehavior: Flickable.DragAndOvershootBounds
    5. snapMode: ListView.SnapToItem
    6. highlightRangeMode: ListView.ApplyRange
    7. anchors.right: parent.right
    8. anchors.rightMargin: 0
    9. anchors.bottom: parent.top
    10. anchors.bottomMargin: -128
    11. anchors.left: parent.left
    12. anchors.leftMargin: 0
    13. anchors.top: parent.top
    14. anchors.topMargin: 0
    15. orientation: ListView.Horizontal
    16. flickableDirection: Flickable.HorizontalFlick
    17. antialiasing: true
    18. spacing: 16
    19. delegate: UePeopleItemDelegate
    20. {
    21. id: uePersonDelegate
    22.  
    23. ueParamPersonImage: "//image://UePeopleModel/"*uePeopleModel.ueImage
    24. ueParamPersonName: "Test"//UePersonNameRole
    25. }
    26. model: uePeopleModel
    27. }
    To copy to clipboard, switch view to plain text mode 
    and here is ListView's delegate:
    Qt Code:
    1. import QtQuick 2.3
    2.  
    3. Item
    4. {
    5. id: uePeopleItemDelegate
    6.  
    7. property string ueParamPersonImage
    8. property string ueParamPersonName
    9.  
    10. width: 256
    11. height: 256
    12. antialiasing: true
    13.  
    14. clip: true
    15.  
    16. Rectangle
    17. {
    18. id: ueRectangleMain
    19. color: "#000000"
    20.  
    21. radius: 16
    22. anchors.fill: parent
    23. antialiasing: true
    24. border.color: "#ffffff"
    25. border.width: 4
    26. clip: true
    27. //opacity: 0.7
    28.  
    29. Grid
    30. {
    31. antialiasing: true
    32. anchors.rightMargin: 12
    33. anchors.leftMargin: 12
    34. anchors.bottomMargin: 12
    35. anchors.topMargin: 12
    36. anchors.fill: parent
    37. spacing: 4
    38. rows: 2
    39. columns: 1
    40. }
    41.  
    42. Row
    43. {
    44. id: ueRowImage
    45. anchors.rightMargin: 12
    46. anchors.leftMargin: 12
    47. anchors.bottom: parent.bottom
    48. anchors.right: parent.right
    49. anchors.left: parent.left
    50. anchors.top: parent.top
    51. anchors.bottomMargin: 48
    52. anchors.topMargin: 12
    53. }
    54.  
    55. Image
    56. {
    57. id: uePersonImage
    58. x: 12
    59. y: 12
    60. width: 232
    61. height: 196
    62. antialiasing: true
    63. fillMode: Image.PreserveAspectFit
    64. source: ueParamPersonImage
    65. }
    66.  
    67. Column
    68. {
    69. id: ueColumnPeopleInfo
    70. x: 12
    71. y: 214
    72. width: 232
    73. height: 30
    74. spacing: 0
    75. }
    76.  
    77. Text
    78. {
    79. id: ueTextPersonName
    80. x: 12
    81. y: 214
    82. width: 232
    83. height: 30
    84. color: "#ffffff"
    85. text: ueParamPersonName
    86. font.bold: true
    87. verticalAlignment: Text.AlignVCenter
    88. horizontalAlignment: Text.AlignHCenter
    89. font.pixelSize: 16
    90. }
    91. }
    92. }
    To copy to clipboard, switch view to plain text mode 
    The number of erros is consistent with number of records that I wish to display. What is now wrong?!
    Qt 5.3 Opensource & Creator 3.1.2

  22. #17
    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

    The image URL must be something like
    "image://providername/imageid"

    providername is what you register your image provider with, imageid is what your model returns for the image role in data().

    Qt Code:
    1. delegate: UePeopleItemDelegate
    2. {
    3. id: uePersonDelegate
    4.  
    5. ueParamPersonImage: "image://UePeopleModel/" + model.uePeopleModel.ueImage
    6. }
    To copy to clipboard, switch view to plain text mode 
    Assuming that your roleNames() method has a mapping of "ueImage" to the numerical UePeopleModel::ueRoleImage

    From the log output I would guess that you are not using an image URL, thus the value returned from the model is considered a relative filename, your delegate is inside the Qt resource system under "delegates" and the value you pass back from then model is "nan".

    Cheers,
    _

  23. #18
    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

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

    Quote Originally Posted by anda_skoa View Post
    The image URL must be something like
    "image://providername/imageid"

    providername is what you register your image provider with, imageid is what your model returns for the image role in data().

    Qt Code:
    1. delegate: UePeopleItemDelegate
    2. {
    3. id: uePersonDelegate
    4.  
    5. ueParamPersonImage: "image://UePeopleModel/" + model.uePeopleModel.ueImage
    6. }
    To copy to clipboard, switch view to plain text mode 
    Assuming that your roleNames() method has a mapping of "ueImage" to the numerical UePeopleModel::ueRoleImage

    From the log output I would guess that you are not using an image URL, thus the value returned from the model is considered a relative filename, your delegate is inside the Qt resource system under "delegates" and the value you pass back from then model is "nan".

    Cheers,
    _
    I've changed delegate params to:
    Qt Code:
    1. ListView
    2. {
    3. id: uePeopleListView
    4. boundsBehavior: Flickable.DragAndOvershootBounds
    5. snapMode: ListView.SnapToItem
    6. highlightRangeMode: ListView.ApplyRange
    7. anchors.right: parent.right
    8. anchors.rightMargin: 0
    9. anchors.bottom: parent.top
    10. anchors.bottomMargin: -128
    11. anchors.left: parent.left
    12. anchors.leftMargin: 0
    13. anchors.top: parent.top
    14. anchors.topMargin: 0
    15. orientation: ListView.Horizontal
    16. flickableDirection: Flickable.HorizontalFlick
    17. antialiasing: true
    18. spacing: 16
    19. delegate: UePeopleItemDelegate
    20. {
    21. id: uePersonDelegate
    22.  
    23. ueParamPersonImage: "image://UePeopleModel/" + model.uePeopleModel.ueRoleImage
    24. ueParamPersonName: model.uePeopleModel.ueRoleName
    25. }
    26. model: uePeopleModel
    27. }
    To copy to clipboard, switch view to plain text mode 
    Now I am getting following errors:
    qrc:/main.qml:52: TypeError: Cannot read property 'UePersonNameRole' of undefined
    qrc:/main.qml:51: TypeError: Cannot read property 'ueRoleImage' of undefined
    qrc:/main.qml:52: TypeError: Cannot read property 'UePersonNameRole' of undefined
    qrc:/main.qml:51: TypeError: Cannot read property 'ueRoleImage' of undefined
    qrc:/main.qml:52: TypeError: Cannot read property 'UePersonNameRole' of undefined
    qrc:/main.qml:51: TypeError: Cannot read property 'ueRoleImage' of undefined
    qrc:/main.qml:52: TypeError: Cannot read property 'UePersonNameRole' of undefined
    qrc:/main.qml:51: TypeError: Cannot read property 'ueRoleImage' of undefined
    qrc:/main.qml:52: TypeError: Cannot read property 'UePersonNameRole' of undefined
    qrc:/main.qml:51: TypeError: Cannot read property 'ueRoleImage' of undefined
    Here is again UePeopleModel class header, which are ueRoleName and ueRoleImage declared in:
    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 <QtSql/QSqlError>
    11. #include <QtSql/QSqlQueryModel>
    12. #include <QtSql/QSqlRecord>
    13. #include <QModelIndex>
    14. #include <QQuickImageProvider>
    15. #include <QByteArray>
    16. #include <QSqlRecord>
    17. #include <QDebug>
    18.  
    19. #include "../settings/uedefaults.h"
    20. #include "../settings/uetypes.h"
    21.  
    22. class UePeopleModel : public QSqlQueryModel,
    23. public QQuickImageProvider
    24. {
    25. Q_OBJECT
    26.  
    27. public:
    28. UePeopleModel(QObject *parent=0);
    29. ~UePeopleModel();
    30.  
    31. QVariant data(const QModelIndex &index,
    32. int role) const Q_DECL_OVERRIDE;
    33. QImage ueImage(const QString &id) const;
    34. QImage requestImage(const QString &id,
    35. QSize *size,
    36. const QSize &requestedSize);
    37. UeTypeRoles roleNames() const;
    38.  
    39. public:
    40. static const int ueRoleName=Qt::UserRole+1;
    41. static const int ueRoleImage=Qt::UserRole+2;
    42. };
    43.  
    44. #endif // UEPEOPLEMODEL_H
    To copy to clipboard, switch view to plain text mode 
    and here is roleNames()method:
    Qt Code:
    1. UeTypeRoles UePeopleModel::roleNames() const
    2. {
    3. UeTypeRoles roles;
    4. const int iRoleName=UePeopleModel::ueRoleName;
    5. const int iRoleImage=UePeopleModel::ueRoleImage;
    6.  
    7. roles.insert(iRoleName,
    8. "ueRoleName");
    9. roles.insert(iRoleImage,
    10. "ueRoleImage");
    11.  
    12. return roles;
    13. } // roleNames
    To copy to clipboard, switch view to plain text mode 
    What am I still missing? I am getting furious!!!!
    Qt 5.3 Opensource & Creator 3.1.2

  24. #19
    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

    What is UeTypeRoles?

    Why is there "uePeopleModel" between "model" and "ueRoleImage" in QML?

    Cheers,
    _

  25. #20
    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

    Quote Originally Posted by anda_skoa View Post
    What is UeTypeRoles?

    Why is there "uePeopleModel" between "model" and "ueRoleImage" in QML?

    Cheers,
    _
    I've corrected QML model statement into:
    Qt Code:
    1. ListView
    2. {
    3. id: uePeopleListView
    4. boundsBehavior: Flickable.DragAndOvershootBounds
    5. snapMode: ListView.SnapToItem
    6. highlightRangeMode: ListView.ApplyRange
    7. anchors.right: parent.right
    8. anchors.rightMargin: 0
    9. anchors.bottom: parent.top
    10. anchors.bottomMargin: -128
    11. anchors.left: parent.left
    12. anchors.leftMargin: 0
    13. anchors.top: parent.top
    14. anchors.topMargin: 0
    15. orientation: ListView.Horizontal
    16. flickableDirection: Flickable.HorizontalFlick
    17. antialiasing: true
    18. spacing: 16
    19. delegate: UePeopleItemDelegate
    20. {
    21. id: uePersonDelegate
    22.  
    23. ueParamPersonImage: "image://uePeopleModel/"+model.ueRoleImage
    24. ueParamPersonName: model.ueRoleName
    25. }
    26. model: uePeopleModel
    27. }
    To copy to clipboard, switch view to plain text mode 
    and UeTypeRoles is declared in uetypes.h as:
    Qt Code:
    1. #ifndef UETYPES
    2. #define UETYPES
    3.  
    4. #include <QHash>
    5. #include <QByteArray>
    6.  
    7. typedef QHash<int, QByteArray> UeTypeRoles;
    8.  
    9. #endif // UETYPES
    To copy to clipboard, switch view to plain text mode 
    and now am I getting following runtime QML errors:
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Invalid image provider: image://uepeoplemodel/undefined
    qrc:/main.qml:52:32: Unable to assign [undefined] to QString
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Invalid image provider: image://uepeoplemodel/undefined
    qrc:/main.qml:52:32: Unable to assign [undefined] to QString
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Invalid image provider: image://uepeoplemodel/undefined
    qrc:/main.qml:52:32: Unable to assign [undefined] to QString
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Invalid image provider: image://uepeoplemodel/undefined
    qrc:/main.qml:52:32: Unable to assign [undefined] to QString
    qrc:/gui/delegates/UePeopleItemDelegate.qml:55:9: QML Image: Invalid image provider: image://uepeoplemodel/undefined
    qrc:/main.qml:52:32: Unable to assign [undefined] to QString
    Now, I've done step-by-step debugging of method data(), the database IS open and connection to it IS established (checked 5 times), and I've addes some debug code int data() method:
    Qt Code:
    1. QVariant UePeopleModel::data(const QModelIndex &index,
    2. int role) const
    3. {
    4. QVariant value=QVariant();
    5.  
    6. switch(role)
    7. {
    8. case ueRoleImage:
    9. {
    10. for(int iIndex=0; iIndex<this->record().count(); iIndex++)
    11. {
    12. qDebug() << this->record().fieldName(iIndex) << " ";
    13. qDebug() << this->record().value(iIndex) << " ";
    14. } // for
    15. //value=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray();
    16. value=this->record(index.row()).value("IMAGE").toByteArray();
    17. int i=0;
    18. } // case
    19.  
    20. case ueRoleName:
    21. {
    22. value=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
    23. int i=0;
    24. } // case
    25.  
    26. default:
    27. return value;
    28. } // switch
    29.  
    30. qDebug() << value;
    31.  
    32. return value;
    33. } // data
    To copy to clipboard, switch view to plain text mode 
    Here are outputs if qDebug():
    "ID"
    QVariant(QString, "")
    "NAME"
    QVariant(QString, "")
    "APPPASSWORD"
    QVariant(QString, "")
    "CARD"
    QVariant(QString, "")
    "ROLE"
    QVariant(QString, "")
    "VISIBLE"
    QVariant(QString, "")
    "IMAGE"
    QVariant(QByteArray, "")
    Why am I getting empty values from db?!
    P.S.: int i=0; was added for debug purpose, to set breakpoint in this line.
    Last edited by MarkoSan; 24th August 2015 at 09:32.
    Qt 5.3 Opensource & Creator 3.1.2

Similar Threads

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