Results 1 to 14 of 14

Thread: [PyQT] QDataWidgetMapper and Custom Widget

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2015
    Posts
    11
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: [PyQT] QDataWidgetMapper and Custom Widget

    Could you be more precise or ideally write the piece of code you mentionned because I do not see what you mean.

    Cheers,

    Vincent

  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: [PyQT] QDataWidgetMapper and Custom Widget

    I haven't done any PyQt programming myself, but maybe something like
    Qt Code:
    1. self.dataMapper.addMapping(self.colorWidget, 1, "color")
    2. self.colorWidget.sigDataChanged.connect(self.dataMapper.submit);
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  3. #3
    Join Date
    Jan 2015
    Posts
    11
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: [PyQT] QDataWidgetMapper and Custom Widget

    I did not manage to make it working properly. By changing the policy of the dataMapper to Manual, I get plenty of errors. But I may not use the method correctly. I just did something like:
    Qt Code:
    1. self.dataMapper.submit()
    To copy to clipboard, switch view to plain text mode 
    but it is not working.

    It tried few other things and I noticed something which appear very strange to me. When I change the color attribute of my colorWidget with the QColorDialog, I then write the name of the color in the QLineEdit and modify the icon of the QPushButton. If I change the selected object within my treeView, the change is not stored in the model (we already knew that). However, if I set the focus on the QLineEdit and I press manually enter (to force the widget to emit the returnPressed signal), then the color name is stored into the model (the setData method is called). I tried to reproduce programmaticaly this behaviour by changing the focus on the QLineEdit and by emitting manually the returnPressed signal, but it does not solve my problem. I still have to interact with my widget to force the setData method to be called. Strange isn't it? I start to feel really dumb. This problem should have a simple solution, but I don't find it.

    In attachment the last version of the example (it may be clearer for you to directly test the code).

    Any help would be highly welcomed!

    Thanks in advance for your time.

    Cheers,

    Vincent
    Attached Files Attached Files

  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: [PyQT] QDataWidgetMapper and Custom Widget

    So you connect to a local slot and that one calls submit(), should work as well.

    Is the slot being invoked?

    it definitely works in C++. I have a color editing widget and connect its signal to the datawidgetmapper's submit() slot and whenever I change color, the model is update accordingly.

    Qt Code:
    1. #ifndef COLOREDITOR_H
    2. #define COLOREDITOR_H
    3.  
    4. #include <QColor>
    5. #include <QWidget>
    6.  
    7. class QLineEdit;
    8.  
    9. class ColorEditor : public QWidget
    10. {
    11. Q_OBJECT
    12. Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
    13.  
    14. public:
    15. explicit ColorEditor(QWidget *parent = 0);
    16.  
    17. QColor color() const;
    18.  
    19. signals:
    20. void colorChanged(const QColor &color);
    21.  
    22. public slots:
    23. void setColor(const QColor &color);
    24.  
    25. private:
    26. QColor m_color;
    27. QLineEdit *m_lineEdit;
    28.  
    29. private slots:
    30. void onButtonClicked();
    31. };
    32.  
    33. #endif // COLOREDITOR_H
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #include "coloreditor.h"
    2.  
    3. #include <QColorDialog>
    4. #include <QHBoxLayout>
    5. #include <QLineEdit>
    6. #include <QPushButton>
    7.  
    8. ColorEditor::ColorEditor(QWidget *parent)
    9. : QWidget(parent)
    10. {
    11. QHBoxLayout *hbox = new QHBoxLayout(this);
    12.  
    13. m_lineEdit = new QLineEdit(this);
    14. hbox->addWidget(m_lineEdit);
    15.  
    16. QPushButton *button = new QPushButton("...", this);
    17. hbox->addWidget(button);
    18. connect(button, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
    19. }
    20.  
    21. QColor ColorEditor::color() const
    22. {
    23. return m_color;
    24. }
    25.  
    26. void ColorEditor::setColor(const QColor &color)
    27. {
    28. if (color == m_color) {
    29. return;
    30. }
    31.  
    32. m_color = color;
    33. m_lineEdit->setText(m_color.name());
    34.  
    35. emit colorChanged(color);
    36. }
    37.  
    38. void ColorEditor::onButtonClicked()
    39. {
    40. const QColor color = QColorDialog::getColor(m_color, this);
    41. if (!color.isValid()) {
    42. return;
    43. }
    44.  
    45. setColor(color);
    46. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. ui->tableView->setModel(model);
    2.  
    3. QDataWidgetMapper *mapper = new QDataWidgetMapper(this);
    4. mapper->setModel(model);
    5. mapper->addMapping(ui->name, 0);
    6. mapper->addMapping(ui->color, 1, "color");
    7. mapper->toFirst();
    8.  
    9. connect(ui->color, SIGNAL(colorChanged(QColor)), mapper, SLOT(submit()));
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  5. #5
    Join Date
    Jan 2015
    Posts
    11
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: [PyQT] QDataWidgetMapper and Custom Widget

    I finally managed to make it working! Your code is exactly the same as I tried before my last post and I did not manage to make it working because of a recursivity problem (the sigDataChanged signal was directly emitted in the setColor method).

    I had to change a little bit the code :
    Qt Code:
    1. class ColorWidget(QWidget):
    2. sigDataChanged = pyqtSignal(str)
    3. def __init__(self, color=None):
    4. some python code here
    5. self.btnColor.clicked.connect(self.changeColor)
    6.  
    7. def changeColor(self):
    8. colorInit = QColor()
    9. colorInit.setNamedColor(self._color)
    10. color = QColorDialog.getColor(colorInit, self, "Select a color")
    11. if color.isValid():
    12. self.ldtColor.setText(color.name())
    13. self.setColor(color.name())
    14. self.sigDataChanged.emit(self._color)
    15.  
    16. def updateIcon(self):
    17. pixmap = QPixmap(24, 24)
    18. newcolor = QColor()
    19. newcolor.setNamedColor(self._color)
    20. pixmap.fill(newcolor)
    21. icon = QIcon(pixmap)
    22. self.btnColor.setIcon(icon)
    23.  
    24. def getColor(self):
    25. return self._color
    26.  
    27. def setColor(self, newColor):
    28. self._color = newColor
    29. self.ldtColor.setText(newColor)
    30. self.updateIcon()
    31.  
    32. color = pyqtProperty(str, fget=getColor, fset=setColor)
    To copy to clipboard, switch view to plain text mode 
    I just emit the sigDataChanged signal after the setColor method has been called. Finally, I update the model by connecting this signal to the submit slot of the QDataWidgetMapper in the appropriate PropertiesEditor class (as you mentionned).
    Qt Code:
    1. self.colorWidget.sigDataChanged.connect(self.dataMapper.submit)
    To copy to clipboard, switch view to plain text mode 

    Problem solved. I close the thread.

    Thank you very much anda_skoa for your time and help .

    Cheers,

    Vincent

  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: [PyQT] QDataWidgetMapper and Custom Widget

    Quote Originally Posted by Vincent Le Saux View Post
    I finally managed to make it working! Your code is exactly the same as I tried before my last post and I did not manage to make it working because of a recursivity problem (the sigDataChanged signal was directly emitted in the setColor method).
    My guess would be that this is a problem caused by not checking for actual change.

    I do that in setColor(), so the signal is only emitted if the color actually changes.

    But maybe PyQt behaves differently in some other aspect.

    Cheers,
    _

  7. #7
    Join Date
    Jan 2015
    Posts
    11
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: [PyQT] QDataWidgetMapper and Custom Widget

    You are definitely right! I just check for changes in the setColor method, and the recursivity problem disappears.

    PyQt and Qt behaves exactly the same way on this aspect.

    Once again, thank you!

    Cheers,

    Vincent

Similar Threads

  1. QDataWidgetMapper and custom widget - read value
    By Hostel in forum Qt Programming
    Replies: 3
    Last Post: 11th May 2013, 12:07
  2. Using QDataWidgetMapper with custom types
    By Zanyinj in forum Qt Programming
    Replies: 2
    Last Post: 25th August 2011, 09:42
  3. [PyQt] Creating custom widget
    By asik in forum Newbie
    Replies: 1
    Last Post: 2nd December 2010, 14:33
  4. Custom QLineEdit to store NULL with QDataWidgetMapper
    By certqt in forum Qt Programming
    Replies: 3
    Last Post: 9th November 2010, 13:15
  5. Custom Widgets to PyQt
    By prashant in forum Qt Programming
    Replies: 0
    Last Post: 24th September 2009, 15:17

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.