Skip to content
  • 0 Votes
    7 Posts
    2k Views
    V

    Yes, I have mouse tracking enabled.

    Maybe my description of the issue was not very clear, sorry. When I click for the first time on the button, it does not change its style to QStyle.State_Sunken and then back to QStyle.State_Raised on release, this happens only on the every second click. Also button does not change its style on mouse hover.

    Here is a minimal example

    import sys from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * class MyDelegate(QStyledItemDelegate): def __init__(self): super(MyDelegate, self).__init__() self.buttonRect = None def sizeHint(self, option, index): fm = QFontMetrics(option.font) return QSize(150, fm.height() * 5 + fm.leading()) def paint(self, painter, option, index): name = index.data(Qt.DisplayRole) description = index.data(Qt.UserRole + 1) btnStyle = QStyle.State(index.data(Qt.UserRole + 2)) nameFont = QFont(option.font) nameFont.setWeight(QFont.Weight.Bold) fm = QFontMetrics(nameFont) padding = fm.lineSpacing() // 2 nameRect = QRect(option.rect) nameRect.setLeft(nameRect.left() + padding) nameRect.setTop(nameRect.top() + padding) nameRect.setRight(nameRect.right() - padding) nameRect.setHeight(fm.lineSpacing()) descrRect = QRect(option.rect) descrRect.setLeft(descrRect.left() + padding) descrRect.setTop(nameRect.bottom()) descrRect.setRight(descrRect.right() - padding) descrRect.setHeight(fm.lineSpacing()) btnText = "Add" textWidth = fm.width(btnText) self.btnRect = QRect(option.rect) self.btnRect.setLeft(descrRect.right() - textWidth * 2) self.btnRect.setTop(descrRect.bottom() + padding) self.btnRect.setRight(descrRect.right() - padding) self.btnRect.setHeight(fm.lineSpacing() * 2) borderRect = QRect(option.rect.marginsRemoved(QMargins(4, 4, 4, 4))) painter.save() pen = painter.pen() if option.state & QStyle.State_MouseOver: pp = QPen(option.palette.highlight().color()) pp.setWidth(2) painter.setPen(pp) painter.drawRect(borderRect) painter.setPen(pen) painter.setFont(nameFont) elided_text = fm.elidedText(name, Qt.ElideRight, nameRect.width()) painter.drawText(nameRect, Qt.AlignLeading, elided_text) painter.setFont(option.font) fm = QFontMetrics(QFont(option.font)) elided_text = fm.elidedText(description, Qt.ElideRight, descrRect.width()) painter.drawText(descrRect, Qt.AlignLeading, elided_text) button = QStyleOptionButton() button.text = btnText button.state = btnStyle button.rect = self.btnRect QApplication.style().drawControl(QStyle.CE_PushButton, button, painter) painter.restore() def editorEvent(self, event, model, option, index): if self.btnRect.contains(event.pos()): if event.type() == QEvent.MouseButtonPress: model.setData(index, QStyle.State_Sunken, Qt.UserRole + 2) elif event.type() == QEvent.MouseButtonRelease: model.setData(index, QStyle.State_Raised, Qt.UserRole + 2) self.do_something() else: model.setData(index, QStyle.State_Enabled | QStyle.State_HasFocus, Qt.UserRole + 2) else: model.setData(index, QStyle.State_Enabled, Qt.UserRole + 2) return super(MyDelegate, self).editorEvent(event, model, option, index) def do_something(self): print("button clicked") if __name__ == "__main__": app = QApplication(sys.argv) model = QStandardItemModel() for i in range(10): item = QStandardItem() item.setData(f"Item {i}", Qt.DisplayRole) item.setData("Item description, can be very long", Qt.UserRole + 1) item.setData(QStyle.State_Enabled, Qt.UserRole + 2) model.appendRow(item) listView = QListView() listView.setMouseTracking(True) listView.setItemDelegate(MyDelegate()) listView.setModel(model) listView.show() app.exec()
  • 0 Votes
    7 Posts
    2k Views
    mrjjM

    Hi
    Something like this could work, using a place holder for a label and a button
    will get you this
    http://postimg.org/image/9lhnsha15/
    you still need to hook up button&label for it to do something :)

    #include "mainwindow.h" #include <QApplication> #include <QCheckBox> #include <QRadioButton> #include <QPushButton> #include <QVBoxLayout> #include <QLabel> #include <QFile> #include <QMessageBox> #include <QTextStream> void CreateItem ( QListWidget * TheList , QString& TheText ) { QListWidgetItem * item = new QListWidgetItem ( "" ); TheList->addItem ( item ); // add a place hodler for label and button QWidget * w = new QWidget(); w->setLayout ( new QHBoxLayout() ); QPushButton *but = new QPushButton ( "Do it" ); QLabel *lab = new QLabel ( TheText ); // make row a bit bigger item->setSizeHint ( QSize ( item->sizeHint().width(), 30 ) ); // add the label and button to the layout w->layout()->addWidget ( lab ); w->layout()->addWidget ( but ); // reduce the space around it abit w->layout()->setContentsMargins ( 1, 1, 1, 1 ); // set this combined widget for the row TheList->setItemWidget ( item, w ); } int main ( int argc, char ** argv ) { QApplication app ( argc, argv ); QListWidget * list = new QListWidget(); list->setGeometry(50,50,400,200); QFile file ( "e:/mylist.txt" ); if ( !file.open ( QIODevice::ReadOnly ) ) { QMessageBox::information ( 0, "error", file.errorString() ); } QTextStream in ( &file ); while ( !in.atEnd() ) { QString line = in.readLine(); CreateItem ( list, line ); } file.close(); list->show(); return app.exec(); };