Results 1 to 8 of 8

Thread: display image from database using c++ model

  1. #1
    Join Date
    Jun 2016
    Posts
    99
    Thanks
    18
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: display image from database using c++ model

    I'm having some issues understanding how to display an image stored in a database in QML I would like to use a C++ model to do this. I believe from what I seen I will need an QQuickImageProvider and to over ride the requestImage() method.

    Not quite sure how to set up the Image provider - subclass the image provider and over ride requestImage() ?

    Not sure how to use the model and Image provider to display image in QML scrollView - model combines with ImageProvider to display image ?

    I have a drop list for displaying the images name and once a user selects a image from the list I want the image to load into a scroll view...

    I set up my database schema as such:

    Qt Code:
    1. "CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)"
    To copy to clipboard, switch view to plain text mode 

    QML code
    Qt Code:
    1. Item {
    2. id:checkList_item
    3. implicitHeight: 600
    4. implicitWidth: 1000
    5.  
    6. signal exit()
    7.  
    8. Rectangle {
    9. id: checkList_Rect
    10. anchors.fill: parent
    11. radius: 10
    12. border.width:4
    13. border.color: "black"
    14. layer.enabled: true
    15. enabled: true
    16. opacity: enabled ? 1.0 : .3
    17. layer.effect: DropShadow {
    18. horizontalOffset: 8
    19. verticalOffset: 8
    20. radius: 8.0
    21. samples: 16
    22. color: "#80000000"
    23. source: checkList_Rect
    24. }
    25. gradient: Gradient {
    26. GradientStop {
    27. position: 0
    28. color: "#ffffff"
    29. }
    30.  
    31. GradientStop {
    32. position: 1
    33. color: "#262626"
    34. }
    35. }
    36. //---Saves check list to database---//
    37. Action{
    38. id: action_saveCheckList
    39. onTriggered: {
    40. /*
    41.   * saves check list to database
    42.   * saves the date the check list was verfied
    43.   * operator that verified check list
    44.   * Engineer who verified check list
    45.   */
    46. }
    47. }
    48.  
    49. //---Closes Check List Dialog---//
    50. Action{
    51. id: action_exit
    52. enabled:!inSequence
    53. onTriggered: {
    54. //checkList_item.exit();
    55. window_contents.state = ""
    56. }
    57. }
    58.  
    59. //---Calls function after QML loads---//
    60. Component.onCompleted: {
    61. //---calls initalize function--//
    62. PictureModel.init();
    63. }
    64.  
    65. FocusScope{
    66. id: focusScope1
    67. anchors.rightMargin: 0
    68. anchors.bottomMargin: 0
    69. anchors.leftMargin: 0
    70. anchors.topMargin: 0
    71. anchors.fill:parent
    72.  
    73. //---List Check List Currently in the database---//
    74. ComboBox {
    75. id: checkList_comboBox
    76. width: 130
    77. height: 48
    78. anchors.left: parent.left
    79. anchors.leftMargin: 50
    80. anchors.top: parent.top
    81. anchors.topMargin: 41
    82. implicitHeight: 30
    83. implicitWidth: 130
    84. KeyNavigation.tab: addCheckListItem
    85. activeFocusOnTab: true
    86. model: PictureModel
    87. textRole: "picName"
    88. style: userListCombo
    89. Keys.onReturnPressed: {
    90. checkList_comboBox.focus = false;
    91. addItem.focus = true;
    92. }
    93. }
    94.  
    95. //---Component for comboBox Style---//
    96. Component {
    97. id: userListCombo
    98. ComboBoxStyle {
    99. id: userListcomboxstyle
    100. textColor: "black"
    101. selectionColor: "yellow"
    102. selectedTextColor: "black"
    103. background: Rectangle {
    104. id: comboBackgroundRect
    105. color: "#f9f9f9"
    106. radius: 8
    107. height: 22
    108. width: 67
    109. border.color: control.activeFocus ? "yellow" : "#242424"
    110. border.width: control.activeFocus ? 4 : 2
    111. Image {
    112. id: name
    113. width: 12
    114. height: 12
    115. anchors.verticalCenter: parent.verticalCenter
    116. anchors.right: parent.right
    117. anchors.rightMargin: 5
    118. source: "/combo_expand.png"
    119. }
    120. }
    121. }
    122. }
    123.  
    124. //---Rect to hold Image---//
    125. Rectangle {
    126. id: chekListView_rect
    127. radius: 8
    128. width: 1000
    129. height: 400
    130. anchors.left: parent.left
    131. anchors.leftMargin: 10
    132. anchors.right: parent.right
    133. anchors.rightMargin: 10
    134. anchors.verticalCenter: parent.verticalCenter
    135. anchors.verticalCenterOffset: -5
    136. border{
    137. color: "black"
    138. width: 3
    139. }
    140. //---Adds ScrollBars---//
    141. ScrollView{
    142. id: userEvent_scrollView
    143. anchors.fill: parent
    144. //---Enables flickable Area---//
    145. flickableItem.interactive: true
    146. verticalScrollBarPolicy: Qt.ScrollBarAsNeeded
    147. style: edit_scrollbar_style
    148. //---Display image from C++ model---//
    149. Image{
    150. //source:
    151. }
    152. }
    153. }
    154.  
    155. //---Custom ScrollBar Component---//
    156. Component{
    157. id: edit_scrollbar_style
    158. ScrollViewStyle {
    159. transientScrollBars: false
    160. handle: Item {
    161. implicitWidth: 17
    162. implicitHeight: 25
    163. Rectangle {
    164. color: "#424246"
    165. radius: 6
    166. anchors.fill: parent
    167. anchors.topMargin: 6
    168. anchors.leftMargin: 4
    169. anchors.rightMargin: 4
    170. anchors.bottomMargin: 6
    171. }
    172. }
    173. decrementControl: Rectangle{
    174. implicitWidth: 17
    175. implicitHeight: 17
    176. radius: 6
    177. color:"#626262"
    178.  
    179. Image{
    180. anchors.centerIn: parent
    181. width: 15
    182. height: 15
    183. source: "up_arrow.png"
    184. }
    185. Rectangle {
    186. implicitWidth: 17
    187. implicitHeight: 5
    188. color:"#626262"
    189. anchors.bottom: parent.bottom
    190. anchors.horizontalCenter: parent.horizontalCenter
    191. }
    192.  
    193. }
    194. incrementControl: Rectangle{
    195. implicitWidth: 17
    196. implicitHeight: 17
    197. radius: 6
    198. color:"#626262"
    199. Image{
    200. anchors.centerIn: parent
    201. width: 15
    202. height: 15
    203. source: "down_arrow.png"
    204. }
    205. Rectangle {
    206. anchors.top: parent.top
    207. anchors.horizontalCenter: parent.horizontalCenter
    208. implicitWidth: 17
    209. implicitHeight: 5
    210. color:"#626262"
    211. }
    212.  
    213. }
    214. scrollBarBackground: Rectangle {
    215. implicitWidth: 17
    216. implicitHeight: 25
    217. color:"grey"
    218. }
    219.  
    220. }
    221. }
    222. }
    223. }
    224. }
    To copy to clipboard, switch view to plain text mode 


    Added after 20 minutes:


    C++ here is the model code

    header prototype
    Qt Code:
    1. //---Data struct for stored checkLists---//
    2. struct PictureModelStruct{
    3. QString id;
    4. QString picname;
    5. QPixmap pic;
    6. };
    7.  
    8. class PictureModel : public QAbstractListModel{
    9.  
    10. Q_OBJECT
    11.  
    12. public:
    13. explicit PictureModel(QObject *parent = 0);
    14.  
    15. ~PictureModel();
    16.  
    17. void setContext(QQmlContext* root);
    18.  
    19. Q_INVOKABLE void insertPic();
    20.  
    21. Q_INVOKABLE void displayPic();
    22.  
    23. enum pictureRoles{idRole= Qt::UserRole + 1, nameRole, picRole};
    24.  
    25. int rowCount(const QModelIndex & parent) const;
    26.  
    27. QHash<int, QByteArray> roleNames() const;
    28.  
    29. QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
    30.  
    31. Q_INVOKABLE void addPicture(const PictureModelStruct &picList);
    32.  
    33. Q_INVOKABLE bool dbConnect();
    34.  
    35. Q_INVOKABLE void init();
    36.  
    37. Q_INVOKABLE bool selectPictureName();
    38.  
    39. signals:
    40. void showBusy(bool busy_state);
    41.  
    42. public slots:
    43.  
    44. private:
    45. //---Databse Class Instances---//
    46. QList<PictureModelStruct> m_picList;
    47. QSqlDatabase m_selectPictureDB;
    48. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. //---Constructor subclasses ListModel & ImageLoader---//
    2. PictureModel::PictureModel(QObject *parent) : QAbstractListModel(parent),
    3. QQuickImageProvider(QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading){
    4.  
    5. }
    6.  
    7. QPixmap PictureModel::requestPixmap(const QString &id, QSize *size, const QSize &reqSize){
    8.  
    9.  
    10. }
    11.  
    12. //---Destructor---//
    13. PictureModel::~PictureModel(){
    14.  
    15. }
    16.  
    17. //---init() is called after QML loads---//
    18. void PictureModel::init(){
    19. //insertPic();
    20. displayPic();
    21. selectPictureName();
    22. }
    23.  
    24. //---Connect to BLOB database---//
    25. bool PictureModel::dbConnect(){
    26. //---check if database is connected---//
    27. if(!m_selectPictureDB.isValid()){
    28. qDebug() << "PictureModel::dbConnect() error in connecting to DB";
    29. m_selectPictureDB = QSqlDatabase::addDatabase("QSQLITE", "conn5");
    30. m_selectPictureDB.setDatabaseName(Paths::root() + "/pictures.db");
    31. qDebug() << "PictureModel::dbConnect() database connection path: "+Paths::root()+"/pictures.db";
    32. m_selectPictureDB.open();
    33.  
    34. QStringList tables = m_selectPictureDB.tables();
    35. if(!tables.contains("picTable")){
    36. QSqlQuery q("", m_selectPictureDB);
    37. q.exec("CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)");
    38. qDebug() << "PictureModel::dbConnect() created picTable";
    39. }
    40. }
    41. else{
    42. qDebug() <<"PictureModel::dbConnect() connected to DB" ;
    43. m_selectPictureDB.open();
    44. }
    45. return m_selectPictureDB.isValid();
    46. }
    47.  
    48. //---Inserts a pic into BLOB database
    49. void PictureModel::insertPic(){
    50. dbConnect();
    51.  
    52. QImage image("flower3.jpg");
    53. qDebug() << image.size();
    54. QByteArray inByteArray;
    55. QBuffer buffer(&inByteArray);
    56. buffer.open(QIODevice::WriteOnly);
    57. image.save(&buffer, "jpg");
    58.  
    59. QSqlQuery query(m_selectPictureDB);
    60. bool sqlBool = query.prepare("INSERT INTO picTable (id, picName, pic) VALUES (?, ?, ?)");
    61. query.addBindValue(5);
    62. query.addBindValue("flower");
    63. query.addBindValue(inByteArray);
    64.  
    65. if(sqlBool){
    66. if(query.exec()){
    67. qDebug() << "PictureModel::insertPic() sql insert executed fine!";
    68. }
    69. }
    70. else{
    71. qDebug() << "PictureModel::isertPic() sql insert did not execute!";
    72. }
    73. }
    74.  
    75. //---Displays pic stored in BLOB database---//
    76. void PictureModel::displayPic(){
    77. dbConnect();
    78. QByteArray outByteArray;
    79. QSqlQuery query(m_selectPictureDB);
    80. bool sqlBool;
    81. sqlBool = query.prepare("SELECT pic FROM picTable");
    82. if (sqlBool){
    83. qDebug() << "prepare sql display pic executed fine!";
    84. if(query.exec()){
    85. qDebug() << "execute sql display pic executed fine!";
    86. }
    87. else{
    88. qDebug() << "execute sql display pic did not execute";
    89. }
    90. }
    91. else{
    92. qDebug() << "prepare sql display pic did not execute";
    93. }
    94.  
    95. PictureModelStruct picList;
    96. beginResetModel();
    97. m_picList.clear();
    98.  
    99. while (query.next()){
    100. picList.id = query.value(0).toString();
    101. picList.picname = query.value(1).toString();
    102. outByteArray = query.value(2).toByteArray();
    103. picList.pic = QPixmap::fromImage(QImage::fromData(outByteArray, "jpg"));
    104. addPicture(picList);
    105. }
    106.  
    107. endResetModel();
    108. emit showBusy(false);
    109. m_selectPictureDB.close();
    110. }
    111.  
    112. //---Function is called in xmui.cpp---//
    113. void PictureModel::setContext(QQmlContext* root){
    114.  
    115. //---Sets rootContext for model to be used in userListModel QML---//
    116. root->setContextProperty("PictureModel", this);
    117. }
    118.  
    119. int PictureModel::rowCount(const QModelIndex &parent) const{
    120. Q_UNUSED(parent);
    121. return m_picList.count();
    122. }
    123.  
    124. QHash<int, QByteArray> PictureModel::roleNames() const{
    125. QHash<int, QByteArray> roleNames;
    126. roleNames.insert(nameRole, "picName");
    127. return roleNames;
    128. }
    129.  
    130. QVariant PictureModel::data(const QModelIndex &index, int role) const{
    131. if (index.row() < 0 || index.row() >= m_picList.count()){
    132. return QVariant();
    133. }
    134.  
    135. QVariant text;
    136.  
    137. if(role == nameRole){
    138. PictureModelStruct pList = m_picList.at(index.row());
    139. text = pList.picname;
    140. }
    141. return text;
    142. }
    143.  
    144. void PictureModel::addPicture(const PictureModelStruct &picList){
    145. beginInsertRows(QModelIndex(), 0, 0);
    146. m_picList.insert(0, picList);
    147. endInsertRows();
    148. }
    149.  
    150. //---Selects name of pictures from DB for display---//
    151. bool PictureModel::selectPictureName(){
    152. dbConnect();
    153. emit showBusy(true);
    154. QSqlQuery selectQuery(m_selectPictureDB);
    155. bool sqlBool;
    156. sqlBool = selectQuery.prepare("SELECT DISTINCT picName FROM picTable ORDER BY picName ASC");
    157. if(sqlBool){
    158. if(selectQuery.exec()){
    159. qDebug()<<"PictureModel::selectPictureName() select picName sql statement executed fine";
    160. }
    161. }
    162. else{
    163. emit xmui->alertMsg(QMessageBox::Warning, "Database selectPicture Error Message 1", "Error: sql select script..."+selectQuery.lastError().text());
    164. qDebug()<<"PictureModel::selectPictureName() Error with sql statement execution " << selectQuery.lastError();
    165. return selectQuery.exec();
    166. }
    167.  
    168. PictureModelStruct picList;
    169. beginResetModel();
    170. m_picList.clear();
    171.  
    172. while (selectQuery.next()){
    173. picList.picname = selectQuery.value(1).toString();
    174. addPicture(picList);
    175. }
    176. endResetModel();
    177. emit showBusy(false);
    178. m_selectPictureDB.close();
    179. return selectQuery.exec();
    180. }
    To copy to clipboard, switch view to plain text mode 

    updated header file

    Qt Code:
    1. //---Data struct for stored checkLists---//
    2. struct PictureModelStruct{
    3. QString id;
    4. QString picname;
    5. QPixmap pic;
    6. };
    7.  
    8. class PictureModel : public QAbstractListModel, QQuickImageProvider{
    9.  
    10. Q_OBJECT
    11.  
    12. public:
    13. explicit PictureModel(QObject *parent = 0);
    14.  
    15. ~PictureModel();
    16.  
    17. void setContext(QQmlContext* root);
    18.  
    19. QPixmap requestPixmap(const QString &id, QSize *size, const QSize &reqSize);
    20.  
    21. Q_INVOKABLE void insertPic();
    22.  
    23. Q_INVOKABLE void displayPic();
    24.  
    25. enum pictureRoles{idRole= Qt::UserRole + 1, nameRole, picRole};
    26.  
    27. int rowCount(const QModelIndex & parent) const;
    28.  
    29. QHash<int, QByteArray> roleNames() const;
    30.  
    31. QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
    32.  
    33. Q_INVOKABLE void addPicture(const PictureModelStruct &picList);
    34.  
    35. Q_INVOKABLE bool dbConnect();
    36.  
    37. Q_INVOKABLE void init();
    38.  
    39. Q_INVOKABLE bool selectPictureName();
    40.  
    41. signals:
    42. void showBusy(bool busy_state);
    43.  
    44. public slots:
    45.  
    46. private:
    47. //---Databse Class Instances---//
    48. QList<PictureModelStruct> m_picList;
    49. QSqlDatabase m_selectPictureDB;
    50. };
    To copy to clipboard, switch view to plain text mode 


    Added after 9 minutes:


    thought about adding a call to requestImage() and pass it the id and image from the database...

    Qt Code:
    1. requestPixmap(picList.id, picList.pic, QSize::scaled(20,20, Qt::IgnoreAspectRatio));
    To copy to clipboard, switch view to plain text mode 


    Added after 7 minutes:


    change form pixMap to Image


    Added after 25 minutes:


    updated c++ functions
    Qt Code:
    1. //---Constructor subclasses ListModel & ImageLoader---//
    2. PictureModel::PictureModel(QObject *parent) : QSqlQueryModel(parent),
    3. QQuickImageProvider(QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading){
    4.  
    5. }
    6.  
    7. QImage PictureModel::requestImage(const QString &id, QSize *size, const QSize &reqSize){
    8. Q_UNUSED(id);
    9. Q_UNUSED(size);
    10. Q_UNUSED(reqSize);
    11. //return QImage::fromData(this->record(id.toInt(), "jpg"));
    12. }
    13.  
    14. //---Destructor---//
    15. PictureModel::~PictureModel(){
    16.  
    17. }
    18.  
    19. //---init() is called after QML loads---//
    20. void PictureModel::init(){
    21. //insertPic();
    22. displayPic();
    23. selectPictureName();
    24. }
    25.  
    26. //---Connect to BLOB database---//
    27. bool PictureModel::dbConnect(){
    28. //---check if database is connected---//
    29. if(!m_selectPictureDB.isValid()){
    30. qDebug() << "PictureModel::dbConnect() error in connecting to DB";
    31. m_selectPictureDB = QSqlDatabase::addDatabase("QSQLITE", "conn5");
    32. m_selectPictureDB.setDatabaseName(Paths::root() + "/pictures.db");
    33. qDebug() << "PictureModel::dbConnect() database connection path: "+Paths::root()+"/pictures.db";
    34. m_selectPictureDB.open();
    35.  
    36. QStringList tables = m_selectPictureDB.tables();
    37. if(!tables.contains("picTable")){
    38. QSqlQuery q("", m_selectPictureDB);
    39. q.exec("CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)");
    40. qDebug() << "PictureModel::dbConnect() created picTable";
    41. }
    42. }
    43. else{
    44. qDebug() <<"PictureModel::dbConnect() connected to DB" ;
    45. m_selectPictureDB.open();
    46. }
    47. return m_selectPictureDB.isValid();
    48. }
    49.  
    50. //---Inserts a pic into BLOB database
    51. void PictureModel::insertPic(){
    52. dbConnect();
    53.  
    54. QImage image("flower3.jpg");
    55. qDebug() << image.size();
    56. QByteArray inByteArray;
    57. QBuffer buffer(&inByteArray);
    58. buffer.open(QIODevice::WriteOnly);
    59. image.save(&buffer, "jpg");
    60.  
    61. QSqlQuery query(m_selectPictureDB);
    62. bool sqlBool = query.prepare("INSERT INTO picTable (id, picName, pic) VALUES (?, ?, ?)");
    63. query.addBindValue(5);
    64. query.addBindValue("flower");
    65. query.addBindValue(inByteArray);
    66.  
    67. if(sqlBool){
    68. if(query.exec()){
    69. qDebug() << "PictureModel::insertPic() sql insert executed fine!";
    70. }
    71. }
    72. else{
    73. qDebug() << "PictureModel::isertPic() sql insert did not execute!";
    74. }
    75. }
    76.  
    77. //---Displays pic stored in BLOB database---//
    78. void PictureModel::displayPic(){
    79. dbConnect();
    80. QByteArray outByteArray;
    81. QSqlQuery query(m_selectPictureDB);
    82. bool sqlBool;
    83. sqlBool = query.prepare("SELECT pic FROM picTable");
    84. if (sqlBool){
    85. qDebug() << "prepare sql display pic executed fine!";
    86. if(query.exec()){
    87. qDebug() << "execute sql display pic executed fine!";
    88. }
    89. else{
    90. qDebug() << "execute sql display pic did not execute";
    91. }
    92. }
    93. else{
    94. qDebug() << "prepare sql display pic did not execute";
    95. }
    96.  
    97. PictureModelStruct picList;
    98. beginResetModel();
    99. m_picList.clear();
    100.  
    101. while (query.next()){
    102. picList.id = query.value(0).toString();
    103. picList.picname = query.value(1).toString();
    104. outByteArray = query.value(2).toByteArray();
    105. picList.pic = QPixmap::fromImage(QImage::fromData(outByteArray, "jpg"));
    106. addPicture(picList);
    107.  
    108. //requestImage(picList.id, QSize(20, 20), QSize(20, 20));
    109. }
    110.  
    111. endResetModel();
    112. emit showBusy(false);
    113. m_selectPictureDB.close();
    114. }
    115.  
    116. //---Function is called in xmui.cpp---//
    117. void PictureModel::setContext(QQmlContext* root){
    118.  
    119. //---Sets rootContext for model to be used in userListModel QML---//
    120. root->setContextProperty("PictureModel", this);
    121. }
    122.  
    123. int PictureModel::rowCount(const QModelIndex &parent) const{
    124. Q_UNUSED(parent);
    125. return m_picList.count();
    126. }
    127.  
    128. QHash<int, QByteArray> PictureModel::roleNames() const{
    129. QHash<int, QByteArray> roleNames;
    130. roleNames.insert(nameRole, "picName");
    131. return roleNames;
    132. }
    133.  
    134. QVariant PictureModel::data(const QModelIndex &index, int role) const{
    135. if (index.row() < 0 || index.row() >= m_picList.count()){
    136. return QVariant();
    137. }
    138.  
    139. QVariant text;
    140.  
    141. if(role == nameRole){
    142. PictureModelStruct pList = m_picList.at(index.row());
    143. text = pList.picname;
    144. }
    145. return text;
    146. }
    147.  
    148. void PictureModel::addPicture(const PictureModelStruct &picList){
    149. beginInsertRows(QModelIndex(), 0, 0);
    150. m_picList.insert(0, picList);
    151. endInsertRows();
    152. }
    153.  
    154. //---Selects name of pictures from DB for display---//
    155. bool PictureModel::selectPictureName(){
    156. dbConnect();
    157. emit showBusy(true);
    158. QSqlQuery selectQuery(m_selectPictureDB);
    159. bool sqlBool;
    160. sqlBool = selectQuery.prepare("SELECT DISTINCT picName FROM picTable ORDER BY picName ASC");
    161. if(sqlBool){
    162. if(selectQuery.exec()){
    163. qDebug()<<"PictureModel::selectPictureName() select picName sql statement executed fine";
    164. }
    165. }
    166. else{
    167. emit xmui->alertMsg(QMessageBox::Warning, "Database selectPicture Error Message 1", "Error: sql select script..."+selectQuery.lastError().text());
    168. qDebug()<<"PictureModel::selectPictureName() Error with sql statement execution " << selectQuery.lastError();
    169. return selectQuery.exec();
    170. }
    171.  
    172. PictureModelStruct picList;
    173. beginResetModel();
    174. m_picList.clear();
    175.  
    176. while (selectQuery.next()){
    177. picList.picname = selectQuery.value(1).toString();
    178. addPicture(picList);
    179. }
    180. endResetModel();
    181. emit showBusy(false);
    182. m_selectPictureDB.close();
    183. return selectQuery.exec();
    184. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jfinn88; 25th October 2016 at 20:22.

  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: display image from database using c++ model

    Quote Originally Posted by jfinn88 View Post
    I'm having some issues understanding how to display an image stored in a database in QML I would like to use a C++ model to do this. I believe from what I seen I will need an QQuickImageProvider and to over ride the requestImage() method.
    Yes, that is one option.

    Quote Originally Posted by jfinn88 View Post
    Not quite sure how to set up the Image provider - subclass the image provider and over ride requestImage() ?
    Yes, or the method that returns QImage, depending on what you have. QImage in your case I think.
    And then registering the instance of the provider with the id name scheme it should be used with.

    The documentation has a pretty thorough example in the class' detailed description.

    Quote Originally Posted by jfinn88 View Post
    Not sure how to use the model and Image provider to display image in QML scrollView - model combines with ImageProvider to display image ?
    That is an option, probably the easiest one.

    In your code I am missing where you add/register the image provider and how you add the scheme name used there to the image identifiers your data() method hands out.
    Maybe you are missing these?

    Cheers,
    _

  3. #3
    Join Date
    Jun 2016
    Posts
    99
    Thanks
    18
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: display image from database using c++ model

    Yes I am missing the add/register the image provider not quite sure how to do that will have to read more
    Im guessing I need to register the imageProvider with the QML engine like this ex from the doc
    Qt Code:
    1. QQuickView view;
    2. QQmlEngine *engine = view.engine();
    3. engine->addImageProvider(QLatin1String("colors"), new ColorPixmapProvider);
    To copy to clipboard, switch view to plain text mode 

    once its registered though you call it with the id from the QML Image source property like in the doc
    Qt Code:
    1. Image { source: "image://myimageprovider/image.png" }
    To copy to clipboard, switch view to plain text mode 

    I also get lost with how the "id" and scheme name are used to identify the image from data

    Qt Code:
    1. //---Constructor subclasses ListModel & ImageLoader---//
    2. PictureModel::PictureModel(QObject *parent) : QSqlQueryModel(parent),
    3. QQuickImageProvider(QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading){
    4.  
    5. }
    6.  
    7. QImage PictureModel::requestImage(const QString &id, QSize *size, const QSize &reqSize){
    8. Q_UNUSED(id);
    9. Q_UNUSED(size);
    10. Q_UNUSED(reqSize);
    11. //return QImage::fromData(this->record(id.toInt(), "jpg"));
    12. }
    13.  
    14. //---Destructor---//
    15. PictureModel::~PictureModel(){
    16.  
    17. }
    18.  
    19. //---Function is called in xmui.cpp---//
    20. void PictureModel::setContext(QQmlContext* root){
    21.  
    22. //---Sets rootContext for model to be used in userListModel QML---//
    23. root->setContextProperty("PictureModel", this);
    24. }
    25.  
    26. //---init() is called after QML loads---//
    27. void PictureModel::init(){
    28. //insertPic();
    29. //displayPic();
    30. selectPictureName();
    31. }
    32.  
    33. //---Connect to BLOB database---//
    34. bool PictureModel::dbConnect(){
    35. //---check if database is connected---//
    36. if(!m_selectPictureDB.isValid()){
    37. qDebug() << "PictureModel::dbConnect() error in connecting to DB";
    38. m_selectPictureDB = QSqlDatabase::addDatabase("QSQLITE", "conn5");
    39. m_selectPictureDB.setDatabaseName(Paths::root() + "/pictures.db");
    40. qDebug() << "PictureModel::dbConnect() database connection path: "+Paths::root()+"/pictures.db";
    41. m_selectPictureDB.open();
    42.  
    43. QStringList tables = m_selectPictureDB.tables();
    44. if(!tables.contains("picTable")){
    45. QSqlQuery q("", m_selectPictureDB);
    46. q.exec("CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)");
    47. qDebug() << "PictureModel::dbConnect() created picTable";
    48. }
    49. }
    50. else{
    51. qDebug() <<"PictureModel::dbConnect() connected to DB" ;
    52. m_selectPictureDB.open();
    53. }
    54. return m_selectPictureDB.isValid();
    55. }
    56.  
    57. int PictureModel::rowCount(const QModelIndex &parent) const{
    58. Q_UNUSED(parent);
    59. return m_picList.count();
    60. }
    61.  
    62. QHash<int, QByteArray> PictureModel::roleNames() const{
    63. QHash<int, QByteArray> roleNames;
    64. roleNames.insert(idRole, "id");
    65. roleNames.insert(nameRole, "picName");
    66. roleNames.insert(picRole, "pic");
    67. return roleNames;
    68. }
    69.  
    70. QVariant PictureModel::data(const QModelIndex &index, int role) const{
    71. if (index.row() < 0 || index.row() >= m_picList.count()){
    72. return QVariant();
    73. }
    74.  
    75. QVariant text;
    76. //QImage image;
    77.  
    78. if(role == nameRole){
    79. PictureModelStruct pList = m_picList.at(index.row());
    80. text = pList.picName;
    81. }
    82.  
    83. // if(role == idRole){
    84. // PictureModelStruct pList = m_picList.at(index.row());
    85. // text = pList.id;
    86. // }
    87. // else if(role == picRole){
    88. // PictureModelStruct pList = m_picList.at(index.row());
    89. // image = pList.pic;
    90. // }
    91. return text;
    92. }
    93.  
    94. void PictureModel::addPicture(const PictureModelStruct &picList){
    95. beginInsertRows(QModelIndex(), 0, 0);
    96. m_picList.insert(0, picList);
    97. endInsertRows();
    98. }
    99.  
    100. //---Inserts a pic into database---//
    101. void PictureModel::insertPic(){
    102. dbConnect();
    103.  
    104. QImage image("flower2.jpg");
    105. qDebug() << image.size();
    106. QByteArray inByteArray;
    107. QBuffer buffer(&inByteArray);
    108. buffer.open(QIODevice::WriteOnly);
    109. image.save(&buffer, "jpg");
    110.  
    111. QSqlQuery query(m_selectPictureDB);
    112. bool sqlBool = query.prepare("INSERT INTO picTable (id, picName, pic) VALUES (?, ?, ?)");
    113. query.addBindValue(1);
    114. query.addBindValue("flower2");
    115. query.addBindValue(inByteArray);
    116.  
    117. if(sqlBool){
    118. if(query.exec()){
    119. qDebug() << "PictureModel::insertPic() sql insert executed fine!";
    120. }
    121. }
    122. else{
    123. qDebug() << "PictureModel::isertPic() sql insert did not execute!";
    124. }
    125. }
    126.  
    127. //---Displays pic stored in database---//
    128. void PictureModel::displayPic(){
    129. dbConnect();
    130. QByteArray outByteArray;
    131. QSqlQuery query(m_selectPictureDB);
    132. bool sqlBool;
    133. sqlBool = query.prepare("SELECT pic FROM picTable");
    134. if (sqlBool){
    135. qDebug() << "prepare sql display pic executed fine!";
    136. if(query.exec()){
    137. qDebug() << "execute sql display pic executed fine!";
    138. }
    139. else{
    140. qDebug() << "execute sql display pic did not execute";
    141. }
    142. }
    143. else{
    144. qDebug() << "prepare sql display pic did not execute";
    145. }
    146.  
    147. PictureModelStruct picList;
    148. beginResetModel();
    149. m_picList.clear();
    150. while (query.next()){
    151. picList.id = query.value(0).toString();
    152. picList.picName = query.value(1).toString();
    153. //outByteArray = query.value(2).toByteArray();
    154. //picList.pic = QPixmap::fromImage(QImage::fromData(outByteArray, "jpg"));
    155. addPicture(picList);
    156. //requestImage(picList.id, QSize(20, 20), QSize(20, 20));
    157. }
    158. endResetModel();
    159. emit showBusy(false);
    160. m_selectPictureDB.close();
    161. }
    162.  
    163. //---Selects name of pictures from DB for display---//
    164. bool PictureModel::selectPictureName(){
    165. dbConnect();
    166. emit showBusy(true);
    167. QSqlQuery selectQuery(m_selectPictureDB);
    168. QByteArray outByteArray;
    169. bool sqlBool;
    170. sqlBool = selectQuery.prepare("SELECT DISTINCT picName FROM picTable ORDER BY picName ASC");
    171. if(sqlBool){
    172. if(selectQuery.exec()){
    173. qDebug()<<"PictureModel::selectPictureName() select picName sql statement executed fine";
    174. }
    175. }
    176. else{
    177. emit xmui->alertMsg(QMessageBox::Warning, "Database selectPicture Error Message 1", "Error: sql select script..."+selectQuery.lastError().text());
    178. qDebug()<<"PictureModel::selectPictureName() Error with sql statement execution " << selectQuery.lastError();
    179. return selectQuery.exec();
    180. }
    181.  
    182. PictureModelStruct picList;
    183. beginResetModel();
    184. m_picList.clear();
    185.  
    186. while (selectQuery.next()){
    187. picList.id = selectQuery.value(0).toString();
    188. picList.picName = selectQuery.value(1).toString();
    189. //outByteArray = selectQuery.value(2).toByteArray();
    190. //picList.pic = QPixmap::fromImage(QImage::fromData(outByteArray, "jpg"));
    191. addPicture(picList);
    192. }
    193. endResetModel();
    194. emit showBusy(false);
    195. m_selectPictureDB.close();
    196. return selectQuery.exec();
    197. }
    To copy to clipboard, switch view to plain text mode 

    update:
    cant seem to register the imageProvider properly not sure if im passing the parameter correctly to addImageProvider method
    Qt Code:
    1. QQuickView view;
    2. QQmlEngine *engine = view.engine();
    3. engine->addImageProvider(QLatin1String("picture"), new PictureModel);
    To copy to clipboard, switch view to plain text mode 
    error: QQmlImageProviderBase is an inaccessible base of PictureModel

    I have tried it a couple different ways, am I suppose to pass the class that subclasses imageProvider that is the model and has the requestImage() method in it?
    Last edited by jfinn88; 26th October 2016 at 17:30.

  4. #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: display image from database using c++ model

    Quote Originally Posted by jfinn88 View Post
    Yes I am missing the add/register the image provider not quite sure how to do that will have to read more
    Im guessing I need to register the imageProvider with the QML engine like this ex from the doc
    Yes.
    E.g. rename "setContext" into "registerWithEngine", pass the engine and do both registrations in that method.

    Quote Originally Posted by jfinn88 View Post
    once its registered though you call it with the id from the QML Image source property like in the doc
    yes, exactly.

    Quote Originally Posted by jfinn88 View Post
    I also get lost with how the "id" and scheme name are used to identify the image from data
    Your data() needs to return QUrl objects that use the "image" scheme, your provider id and the image id.

    Cheers,
    _

  5. #5
    Join Date
    Jun 2016
    Posts
    99
    Thanks
    18
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: display image from database using c++ model

    Let me try registering it in my set context function


    Added after 35 minutes:


    Okay I think I have it registered with the qml engine now

    Qt Code:
    1. //---Function is called in xmui.cpp---//
    2. void PictureModel::registerWithEngine(QQmlEngine *engine){
    3.  
    4. //---Sets rootContext for model to be used in userListModel QML---//
    5. engine->rootContext()->setContextProperty("PictureModel", this);
    6.  
    7. //---Registers Image provider with QML Engine---//
    8. engine->addImageProvider(QLatin1String("picture"), new PictureModel);
    9. }
    To copy to clipboard, switch view to plain text mode 

    now I'm not sure how to get the data() method over ridden properly for this situation

    "return QUrl objects that use the "image" scheme, your provider id and the image id."

    I'm not sure how to get the QUrl of the image to return
    The image is stored in a data base its pulled out and then reassembled using QImage::fromImage() & QImage::fromData() in my displayPic() method

    Is the image id just the idRole ?

    I'm not sure what to pass the imageProvider in QML Image source property (imageFromYourProvider.png Is this the provider id ?)

    //Picture is the registered imageProvider...

    Qt Code:
    1. Image{
    2. //source: "image://picture/imageFromYourProvider.png"
    3. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. QVariant PictureModel::data(const QModelIndex &index, int role) const{
    2. if (index.row() < 0 || index.row() >= m_picList.count()){
    3. return QVariant();
    4. }
    5.  
    6. QVariant text;
    7. //QImage image;
    8.  
    9. if(role == nameRole){
    10. PictureModelStruct pList = m_picList.at(index.row());
    11. text = pList.picName;
    12. }
    13.  
    14. // if(role == idRole){
    15. // PictureModelStruct pList = m_picList.at(index.row());
    16. // text = pList.id;
    17. // }
    18. // else if(role == picRole){
    19. // PictureModelStruct pList = m_picList.at(index.row());
    20. // image = pList.pic;
    21. // }
    22. return text;
    23. }
    To copy to clipboard, switch view to plain text mode 

    Do I still need to add the image to my data Struct created for the model ? Or do I create the QUrl for the image instead (just not sure how to create a QUrl for an image)
    Last edited by jfinn88; 26th October 2016 at 18:04.

  6. #6
    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: display image from database using c++ model

    Quote Originally Posted by jfinn88 View Post
    Qt Code:
    1. //---Function is called in xmui.cpp---//
    2. void PictureModel::registerWithEngine(QQmlEngine *engine){
    3.  
    4. //---Sets rootContext for model to be used in userListModel QML---//
    5. engine->rootContext()->setContextProperty("PictureModel", this);
    6.  
    7. //---Registers Image provider with QML Engine---//
    8. engine->addImageProvider(QLatin1String("picture"), new PictureModel);
    9. }
    To copy to clipboard, switch view to plain text mode 
    This looks very wrong.
    Why is there a "new PictureModel" instead of "this"?

    Quote Originally Posted by jfinn88 View Post
    Is the image id just the idRole ?
    The image ID is whatever you use to identifiy a single image.
    The ID is what you get as part of the image provider request call, it needs to enable you to return the correct image.

    So either some index into an internal list or something that you can use to get the data from the database.

    Quote Originally Posted by jfinn88 View Post
    I'm not sure what to pass the imageProvider in QML Image source property (imageFromYourProvider.png Is this the provider id ?)
    yes.

    The URLs have the form of "image://" + image provider name + "/" + imageId

    Quote Originally Posted by jfinn88 View Post
    Do I still need to add the image to my data Struct created for the model ?
    That is you choice.
    If you add the image to the model entry then the id can simply be the row index of that entry.

    Quote Originally Posted by jfinn88 View Post
    Or do I create the QUrl for the image instead (just not sure how to create a QUrl for an image)
    That is also possible.
    The URLs in this case use the "data" scheme. Not sure how these are correctly formatted, though. They carry the image data as part of the URL string, one of the options aside from image provider.

    Cheers,
    _

  7. #7
    Join Date
    Jun 2016
    Posts
    99
    Thanks
    18
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: display image from database using c++ model

    This looks very wrong.
    Why is there a "new PictureModel" instead of "this"?
    I will work on this part and change to this was working from example and forgot to change it.

  8. #8
    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: display image from database using c++ model

    Quote Originally Posted by jfinn88 View Post
    I will work on this part and change to this was working from example and forgot to change it.
    Ah, ok.

    Then your image URLs should be something like "image://picture/somenumber" if you are using the row index into your element list as the image id part.

    Your commented code in requestImage() suggests that you already had that idea, but instead of calling record you can simply access your m_picList and return the "pic" of the respective entry.

    Cheers,
    _

Similar Threads

  1. Replies: 1
    Last Post: 18th October 2015, 13:06
  2. how to remove previous image to display new image in QImage
    By iswaryasenthilkumar in forum Newbie
    Replies: 6
    Last Post: 5th January 2015, 11:53
  3. Replies: 9
    Last Post: 14th February 2013, 13:14
  4. Replies: 2
    Last Post: 17th February 2010, 15:32

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.