Skip to content
  • 0 Votes
    16 Posts
    819 Views
    S

    @SGaist Thank you very much. One last questions before closing this thread:

    Does using setListWigetItem (QListWidget) make an difference in performance compared to just using the widgets inside a scrollarea or is the overhead the same?

    Have a nice day! :)

  • 0 Votes
    19 Posts
    2k Views
    S

    @Chris-Kawa thank you very much. That definitely helped a lot. :)

    I have done the manual positioning now, so all delegates line up with the actual widget. :)

    void ViewLayerItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // Überprüfen Sie, ob der aktuelle Index bearbeitet wird if (index == currentlyEditedIndex) { return; } // Setzen Sie die Werte der SpinBox und CheckBox basierend auf den Modellwerten QString lineEditvalue = index.model()->data(index, Qt::EditRole).toString(); bool checkBoxValue = index.model()->data(index, Qt::CheckStateRole).toBool(); // Laden Sie das Icon und skalieren Sie es QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation); // Berechnen Sie die Position für das Icon int centerY = option.rect.top() + option.rect.height() / 2; int iconY = centerY - scaledPixmap.height() / 2; QPoint iconPos = QPoint(option.rect.left() + 10, iconY); // Zeichnen Sie das Pixmap mit dem QPainter painter->drawPixmap(iconPos, scaledPixmap); // Berechnen Sie die Position und Größe für das LineEdit QRect lineEditRect = option.rect; lineEditRect.setLeft(iconPos.x() + scaledPixmap.width() + 10); // Adjust as needed lineEditRect.setRight(option.rect.right() - 10); // Adjust as needed // Erstellen Sie ein QStyleOptionFrame für das LineEdit QStyleOptionFrame lineEditOption; lineEditOption.lineWidth = 1; // Setzen Sie die Liniendicke auf 1 lineEditOption.rect = lineEditRect; // Zeichnen Sie das LineEdit QApplication::style()->drawControl(QStyle::CE_ShapedFrame, &lineEditOption, painter); // Zeichnen Sie den Text des LineEdits painter->drawText(lineEditOption.rect.adjusted(2,0,0,0), Qt::AlignLeft | Qt::AlignVCenter, lineEditvalue); // Berechnen Sie die Position und Größe für die CheckBox QRect checkBoxRect = option.rect; checkBoxRect.setLeft(lineEditRect.right() - 22); // Adjust as needed checkBoxRect.setRight(option.rect.right() - 10); // Adjust as needed // Erstellen Sie ein QStyleOptionButton für die CheckBox QStyleOptionButton checkBoxOption; checkBoxOption.state = checkBoxValue ? QStyle::State_On : QStyle::State_Off; checkBoxOption.rect = checkBoxRect; // Zeichnen Sie die CheckBox QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBoxOption, painter); }
  • 0 Votes
    5 Posts
    442 Views
    SGaistS

    @StudentScripter For the grouping you have to use an adequate data structure.

    As for hovering, IIRC, you have to have mouse tracking enabled on the view.

  • 0 Votes
    5 Posts
    355 Views
    EmrecpE

    Can anyone share sample code for qlistwidget or qlistview?

  • 0 Votes
    9 Posts
    859 Views
    JonBJ

    @bibasmall
    I'm not understanding what is going on with your const or not. The slot CommitData() must not be const. Is it??

    Hmm, you mean you call it from CEditorDelegate::createEditor(), that is const, so its this is const, and you can't then use that for the slot object? Then I really don't know why it's OK for the connect() to actual slot but not to lambda (I suspect it's this issue, not because the new CommitData(QPushButton *btn) parameter....

    Is your CommitData() const? Doesn't look like it. If you made it const does that allow the connect()?

    UPDATE
    I think this has crossed with your latest. I believe you show there you have found a way. I prefer the second one.

    Basically you have raised a "gotcha": createEditor() is const, and that prevents you from connecting a slot to this inside it, which is something one might well want to do. It (apparently) works when &CEditorDelegate::CommitData is passed on its own as a standalone argument, but not if you try a lambda with this->CommitData(). If the C++ super-experts here see this they might comment....

  • 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
    1 Posts
    914 Views
    No one has replied
  • 0 Votes
    3 Posts
    512 Views
    artwawA

    @SGaist You are, as usual, right and I am the absolute moron :D

    I forgot to take into the account starting point of the cell in paint... Too much time has passed since I had to write the delegate it seems.
    The solution of the problem was correcting the drawPixamp starting point (add opt.rec.x() and opt.rect.y() respectively):

    painter-drawPixmap(QPoint(opt.rect.x()+opt.rect.width()/2,opt.rect.y()+opt.rect.height()/3),px.scaled(opt.rect.width(),opt.rect.height()/2,Qt::KeepAspectRatio,Qt::SmoothTransformation));

    Thank you for this quick reminder!

    Cheers,
    A.

  • 0 Votes
    4 Posts
    552 Views
    B

    @vinaygopal

    "what if i want to access the visibility or a property i have defined in the delegate?"

    There are multiple instances of your delegate, corresponding to the part of the model being displayed. Which instance do you want the property from? If it's a common property that is not specific to a single instance, then the same answer applies - factor it out to the table level and use it in the delegate. If it is a property specific to a delegate instance you are interested in, how do you specify which delegate? Does the data actually belong to the model?

    What is it that you are trying to achieve?

  • 0 Votes
    3 Posts
    507 Views
    V

    @fcarney

    Got it thank you so much :)

  • 0 Votes
    4 Posts
    2k Views
    sierdzioS

    The model should provide this information for you. Create a role in the model which will return the correct value for any given cell. On QML side, just access that role and display it directly. No need for any get() method (which, by the way, is called data() https://doc.qt.io/qt-5/qabstractitemmodel.html#data, not get()).

  • 0 Votes
    3 Posts
    489 Views
    R

    @VRonin Aha, that has got to be it - thank you very much! Sounds like I just need to add a new eventfilter that does nothing but eat keypress events.

  • QML force delegate instantiation

    Unsolved QML and Qt Quick
    2
    0 Votes
    2 Posts
    344 Views
    sierdzioS

    You should not want that. Delegates are only a visual representation of the model, and ListView is designed to only show (and instantiate) what the user needs to see. Forcing it to show everything will decrease performance.

    If you definitely need to generate UI for all elements in a model, use Repeater.

  • 0 Votes
    14 Posts
    4k Views
    RatzzR

    @GrecKo , I mean without the button, when I edit the values of TextEdit, I should be able to get the modified text. I tried via property. It always gave me empty

  • Referencing Column from a delegate

    Unsolved QML and Qt Quick
    4
    0 Votes
    4 Posts
    483 Views
    raven-worxR

    @gabor53
    i meant create a new custom property only for your purpose.

  • 0 Votes
    2 Posts
    463 Views
    J.HilkJ

    @jeanmilost
    I can't answer all your questions, as I'm not an expert on Qt's Model/View system, what I do know is,

    that all models have a QAbstractItemModel as base model and that is also the ABI for all views.
    For that reason alone, you can assign all models to all views. You will however not get a useful representation of all your data in all views.

    As I understand it, and anyone fell me to correct me here, the other higher level classes of models are only there to make your life easier, as in you do not have to implement all functions/functionalities of the whole AbstractItemModel class

  • 0 Votes
    3 Posts
    513 Views
    S

    @VRonin Thanks.
    It worked.
    We have used delegates because we have combobox, lineedit also.
    So we have put check for combobox, not to update via delegate.

  • 0 Votes
    2 Posts
    552 Views
    Christian EhrlicherC

    @gde23 said in QSlider as QStyledItemDelegate: moving slider requires additional mouseclick:

    So is there a way the slider can be grabbed directly from the first click?

    Currently not, no - the first click is the edit trigger.

  • 0 Votes
    6 Posts
    798 Views
    ArtiomA

    It really works!

    Thank you, IntruderExcluder, GrecKo.