Results 1 to 5 of 5

Thread: I thought Q_OBJECT was supposed to empower classes not enfeeble them.

  1. #1
    Join Date
    Dec 2009
    Posts
    11
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default I thought Q_OBJECT was supposed to empower classes not enfeeble them.

    OK, I am creating a simple program just to test out what I've learned. I have successfully created a very simple list model and it works correctly with the table view control. I'm now trying to add functionality to the menu items that allow the user to manipulate the items in the table. Upon first testing it, it was clear that the slot method had not run, even though I connected the QAction signal to the said slot. It then occurred to me that I had not yet added Q_OBJECT to the class declaration of my window class. I was relieved when I realized this, but after I added the macro and tried to compile it using Qt Creator, it generated errors. I can't seem to figure out what the problem is, but the error messages are pointing me to source files I Have no business in and to my constructor declarations in my cpp files.

    I really can't figure out what the problem is, so I'm just going to post the whole thing up here and hope someone has the solution. If it were an algorithmic or syntax blunder, no doubt I would diligently look into it. But I cannot identify what this is.

    Qt Code:
    1. #include <QtGui>
    2.  
    3. #include "AppWnd.h"
    4.  
    5. int main(int argc, char** argv)
    6. {
    7. QApplication app(argc, argv);
    8.  
    9. AppWnd appWnd(0);
    10.  
    11. QObject::connect(&appWnd, SIGNAL(close()), &app, SLOT(quit()));
    12.  
    13. return app.exec();
    14. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #ifndef GMODEL_H
    2. #define GMODEL_H
    3.  
    4. #include <QtGui>
    5. #include <QList>
    6. #include <QPair>
    7.  
    8. class GModel : public QAbstractListModel
    9. {
    10. Q_OBJECT //No problems with this one just to let you know. It works!
    11. QPixmap *m;
    12.  
    13. private:
    14.  
    15. QString extractName(QString &string) const;
    16. QString extractAge(QString &string) const;
    17.  
    18. public:
    19.  
    20. GModel(QObject *parent);
    21. ~GModel();
    22.  
    23. int rowCount(const QModelIndex &parent = QModelIndex()) const;
    24. int columnCount(const QModelIndex &parent = QModelIndex()) const;
    25.  
    26. QVariant data(const QModelIndex &index, int role) const;
    27. QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    28.  
    29. QModelIndex index(int row, int column, const QModelIndex &parent) const;
    30.  
    31. bool setData(const QModelIndex &index, const QVariant &value, int role);
    32. };
    33.  
    34. #endif // GMODEL_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "GModel.h"
    2.  
    3. GModel::GModel(QObject *parent) : QAbstractListModel(parent)
    4. {
    5. m = new QPixmap(20, 20);
    6. m->fill(QColor(0, 0, 255, 255));
    7.  
    8. pl.append(QString("Joe Skurk, 23"));
    9. pl.append(QString("John Skelp, 26"));
    10. pl.append(QString("Flim Barbson, 21"));
    11. pl.append(QString("Flark Timberly, 43"));
    12. pl.append(QString("Jespit Vonvooloo, 15"));
    13. pl.append(QString("Norman Walker, 13"));
    14. }
    15.  
    16. GModel::~GModel()
    17. {
    18. delete m;
    19. }
    20.  
    21. QVariant GModel::headerData(int section, Qt::Orientation orientation, int role) const
    22. {
    23. if (role != Qt::DisplayRole) return QVariant();
    24.  
    25. if (orientation == Qt::Vertical)
    26. {
    27. return QVariant();
    28. }
    29.  
    30. if (orientation == Qt::Horizontal)
    31. {
    32. switch(section)
    33. {
    34. case 0:
    35. return QString("Name");
    36. break;
    37. case 1:
    38. return QString("Age");
    39. break;
    40. }
    41. }
    42.  
    43. return QVariant();
    44. }
    45.  
    46. int GModel::rowCount(const QModelIndex &parent) const
    47. {
    48. return pl.count();
    49. }
    50.  
    51. int GModel::columnCount(const QModelIndex &parent) const
    52. {
    53. return 2;
    54. }
    55.  
    56. QVariant GModel::data(const QModelIndex &index, int role) const
    57. {
    58. if (!index.isValid()) return QVariant();
    59. if (index.row() >= pl.count()) return QVariant();
    60.  
    61. if (role == Qt::DisplayRole)
    62. {
    63. QString data = pl.at(index.row());
    64.  
    65. switch (index.column())
    66. {
    67. case 0:
    68. return extractName(data);
    69. break;
    70. case 1:
    71. return extractAge(data);
    72. break;
    73.  
    74. }
    75. }
    76.  
    77. return QVariant();
    78. }
    79.  
    80. QString GModel::extractName(QString &string) const
    81. {
    82. return string.left(string.indexOf(",")).trimmed();
    83. }
    84.  
    85. QString GModel::extractAge(QString &string) const
    86. {
    87. return string.mid(string.indexOf(",")+1, string.length() - string.indexOf(",")+1);
    88. }
    89.  
    90. QModelIndex GModel::index(int row, int column, const QModelIndex &parent) const
    91. {
    92. return createIndex(row, column, 0);
    93. }
    94.  
    95. bool GModel::setData(const QModelIndex &index, const QVariant &value, int role)
    96. {
    97. if (index.isValid() && role == Qt::EditRole)
    98. {
    99. QString data = pl.at(index.row());
    100. QString name = extractName(data);
    101. QString age = extractAge(data);
    102.  
    103. switch(index.column())
    104. {
    105. case 0:
    106. pl.replace(index.row(), value.toString() + QString(", ") + age);
    107. break;
    108. case 1:
    109. pl.replace(index.row(), name + QString(", ") + value.toString());
    110. break;
    111. }
    112. emit dataChanged(index, index);
    113. return true;
    114. }
    115. return false;
    116. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #ifndef APPWND_H
    2. #define APPWND_H
    3.  
    4. #include <QtGui>
    5. #include "GModel.h"
    6.  
    7. class AppWnd : public QMainWindow
    8. {
    9. Q_OBJECT
    10.  
    11. private:
    12. GModel *gm;
    13.  
    14. public:
    15. AppWnd(QWidget *parent = 0);
    16.  
    17. //void setGModel(GModel *gmodel);
    18.  
    19. public slots:
    20. void createPerson();
    21. void deletePerson();
    22. void changeAge();
    23. void changeName();
    24. };
    25.  
    26. #endif // APPWND_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "AppWnd.h"
    2. #include "AddPersonDialog.h"
    3.  
    4. #include <QtGui>
    5.  
    6. AppWnd::AppWnd(QWidget *parent) : QMainWindow(parent)
    7. {
    8. setWindowTitle("Model/View Testing");
    9. setFixedSize(400, 500);
    10.  
    11. QTableView *lv = new QTableView(this);
    12. gm = new GModel(0);
    13. lv->setModel(gm);
    14.  
    15. //lv->resize(380, 480);
    16. //lv->move(10, 10);
    17.  
    18. gm->setData(gm->index(0, 1, QModelIndex()), QString("50"), Qt::EditRole);
    19.  
    20. QMenuBar *mb = menuBar();
    21.  
    22. QMenu *peopleMenu = mb->addMenu("People");
    23. QAction *a_createPerson = peopleMenu->addAction("Create Person", this, SLOT(createPerson()));
    24. QAction *a_deletePerson = peopleMenu->addAction("Delete Person", this, SLOT(deletePerson()));
    25. peopleMenu->addSeparator();
    26. QAction *a_changeName = peopleMenu->addAction("Change Name", this, SLOT(changeName()));
    27. QAction *a_changeAge = peopleMenu->addAction("Change Age", this, SLOT(changeAge()));
    28.  
    29. setCentralWidget(lv);
    30.  
    31. show();
    32. }
    33.  
    34. void AppWnd::createPerson()
    35. {
    36. AddPersonDialog dlg(this);
    37.  
    38. dlg.exec();
    39. }
    40.  
    41. void AppWnd::deletePerson()
    42. {
    43. }
    44.  
    45. void AppWnd::changeName()
    46. {
    47. }
    48.  
    49. void AppWnd::changeAge()
    50. {
    51. }
    52.  
    53. /*void AppWnd::setGModel(GModel *gmodel)
    54. {
    55.   gm = gmodel;
    56. }*/
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #ifndef ADDPERSONDIALOG_H
    2. #define ADDPERSONDIALOG_H
    3.  
    4. #include <QtGui>
    5.  
    6. class AddPersonDialog : public QDialog
    7. {
    8. Q_OBJECT
    9.  
    10. private:
    11. QLineEdit *name;
    12. QLineEdit *age;
    13.  
    14. public:
    15. AddPersonDialog(QWidget *parent = 0);
    16. QString getName();
    17. QString getAge();
    18. };
    19.  
    20. #endif // ADDPERSONDIALOG_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "AddPersonDialog.h"
    2.  
    3. AddPersonDialog::AddPersonDialog(QWidget *parent) : QDialog(parent, 0)
    4. {
    5. QPushButton *ok = new QPushButton("OK");
    6. QPushButton *cancel = new QPushButton("Cancel");
    7.  
    8. name = new QLineEdit();
    9. age = new QLineEdit();
    10.  
    11. QHBoxLayout *hbl = new QHBoxLayout();
    12. hbl->addWidget(ok);
    13. hbl->addWidget(cancel);
    14.  
    15. QHBoxLayout *hbl2 = new QHBoxLayout();
    16. hbl2->addWidget(name);
    17.  
    18. QHBoxLayout *hbl3 = new QHBoxLayout();
    19. hbl3->addWidget(age);
    20.  
    21. QVBoxLayout *vbl = new QVBoxLayout();
    22. vbl->addLayout(hbl2);
    23. vbl->addLayout(hbl3);
    24. vbl->addLayout(hbl);
    25.  
    26. setLayout(vbl);
    27.  
    28. QObject::connect(ok, SIGNAL(clicked()), this, SLOT(accept()));
    29. QObject::connect(cancel, SIGNAL(clicked()), this, SLOT(reject()));
    30. }
    31.  
    32. QString AddPersonDialog::getName()
    33. {
    34. return name->text();
    35. }
    36.  
    37. QString AddPersonDialog::getAge()
    38. {
    39. return age->text();
    40. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: I thought Q_OBJECT was supposed to empower classes not enfeeble them.

    Are you running 'moc' on the classes you have added Q_OBJECT to? Otherwise you'll get some strange errors as there will be files missing from your compile.

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

    waitingforzion (26th December 2009)

  4. #3
    Join Date
    Dec 2009
    Posts
    11
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: I thought Q_OBJECT was supposed to empower classes not enfeeble them.

    I thought QtCreator does that for me? Doesn't it?

    AppWnd.cpp:7: undefined reference to `vtable for AppWnd'

  5. #4
    Join Date
    Dec 2009
    Posts
    11
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: I thought Q_OBJECT was supposed to empower classes not enfeeble them.

    Quote Originally Posted by fatjuicymole View Post
    Are you running 'moc' on the classes you have added Q_OBJECT to? Otherwise you'll get some strange errors as there will be files missing from your compile.
    Actually, I think you're right. I just realized what the "run qmake" option is for. I was so focused on learning the language and being convenience by Qt Creator, I didn't take the time to learn about moc and what not. Now I see, qt does handle it for me, but I have to click "run qmake" Thank you.

  6. #5
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: I thought Q_OBJECT was supposed to empower classes not enfeeble them.

    Quote Originally Posted by waitingforzion View Post
    Now I see, qt does handle it for me, but I have to click "run qmake"
    Just as a note: You only have to run that option if you add QObject to a class, that hasn't had it before. And sometimes it is necessary to clean your project before building it again.

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

    waitingforzion (26th December 2009)

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.