Using custom QWidgets in QListWidgets



  • QListWidgetItem* exampleUnitQLWIAddress = new QListWidgetItem(tr("example"), ui->UnitList);
    
    QListWidgetItem* exampleButtonAddress = new QListWidgetItem(tr("example"), ui->UnitList);
    
    BioBloomUnit* exampleUnitAddress = new BioBloomUnit(this);
    
    QPushButton* exampleButton = new QPushButton;
    
    exampleUnitQLWIAddress->setSizeHint(exampleUnitAddress->ribbonAddress->sizeHint());
    
    ui->UnitList->setMovement(QListView::Free);
    
    ui->UnitList->setItemWidget(exampleUnitQLWIAddress, exampleUnitAddress->ribbonAddress);
    
    ui->UnitList->addItem(exampleUnitQLWIAddress);
    
    ui->UnitList->addItem(exampleButtonAddress);
    
    ui->UnitList->setItemWidget(exampleButtonAddress, exampleButton);
    
    connect(ui->pushButton, SIGNAL(released()), exampleUnitAddress, SLOT(unitButtonPressSlot()) );
    

    I am kind of new to coding in Qt and am looking for a method to list my custom graphical widgets into a list, the class I have created name 'BioBloomUnit' contains a member class UnitRibbon which is a designed graphical QWidget, this is not appearing in the list whereas the QPushButton is.


  • Qt Champions 2017

    Hi
    QListWidgetItem* exampleUnitQLWIAddress = new QListWidgetItem(tr("example"), ui->UnitList);
    ui->UnitList->setItemWidget(exampleUnitQLWIAddress, exampleUnitAddress->ribbonAddress);

    Are you setting the QListWidgetItem as ItemWidget ??

    should that not be the
    exampleUnitAddress = new BioBloomUnit(this); ?



  • I don't understand :/
    The declaration for that function is:-
    void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)
    and its description is sets the widget in the item
    which I assume means it puts my custom widget inside the QLWI so that it can be added to the list?


  • Qt Champions 2017

    @Hubbard
    Oh, sorry, misread the names it seems.
    But if u insert exampleUnitAddress->ribbonAddress
    are you inserting a widget that lives in other widget ?
    When you insert a QButton its not inside other widget.
    That seems to be the difference ?



  • The QWidget class 'UnitRibbon' (or UnitRibbon *ribbonAddress) is a member class of BioBloomUnit QObject, with a designed UI


  • Lifetime Qt Champion

    Hi,

    Why are you trying to show an inner widget rather than the full BioBloomUnit widget ?



  • @SGaist
    The BioBloomUnit isn't a widget with its own graphics (its a QObject), it stores all of the necessary data for an instance of the unit in my project AS WELL AS its own QWidget unitRibbon which displays some of the data, which I want organised into lists


  • Lifetime Qt Champion

    Then this looks bad. You should decouple the data from their graphic representation aka MVC.

    Since you are already using Qt's related class. You should consider implementing a QAbstractListModel that will wrap your list of BioBloomUnit and use a QListView to show them.

    By the way, what is ribbonAddress for a widget ?



  • ribbonAddress is a pointer to a UnitRibbon class and is a member in BioBloomUnit, its a widget with its own UI file, BioBloomUnit is NOT a widget and is a normal QObject class, I was to display all of the UnitRibbons for each unit in a list.


  • Lifetime Qt Champion

    That I understood, hence my suggestion for a separation of concerns. BioBloomUnit should not care about the GUI that should show the data it represents.



  • Would it be better if the UnitRibbons exist in the mainWindow and instead take BioBloomUnit as an argument (either by constructor or member method) to get their data?



  • so I updated my code to the following

    UnitRibbon* exampleRibbonAddress = new UnitRibbon;
    QListWidgetItem* exampleItemAddress = new QListWidgetItem(ui->UnitList);
    //exampleItemAddress->setSizeHint(exampleRibbonAddress->sizeHint());
    ui->UnitList->setItemWidget(exampleItemAddress, exampleRibbonAddress);
    ui->UnitList->addItem(exampleItemAddress);
    

    Now it only shows the top half of the widget, when the sizeHint is uncommented it becomes invisible entirely


  • Qt Champions 2017

    @Hubbard
    Hi
    Setting size hint is good idea.
    It will use that for widget size when placed on "row"


  • Lifetime Qt Champion

    Might be a silly question but are you sure your properly set the layouts on your widgets ? Having to call sizeHint like that is surprising.



  • I have removed the graphical widget from my class and made it a separate class and now it is displaying, I'm surprised it works like that, however I've run into a different yet related issue:-

    exampleUnitAddress = new BioBloomUnit(this);        //instance example
    
    setupOtherWindows();
    setupPushButtons();
    
    UnitRibbon* exampleRibbonAddress = new UnitRibbon;
    QListWidgetItem* exampleItemAddress = new QListWidgetItem(ui->UnitList);
    exampleItemAddress->setSizeHint(exampleRibbonAddress->size());
    ui->UnitList->setItemWidget(exampleItemAddress, exampleRibbonAddress);
    ui->UnitList->addItem(exampleItemAddress);
    
    //UnitRibbonPressSlot() calls BioBloomUnit::UnitWindow->show()
    
    connect(ui->ExampleButton, SIGNAL(released()), exampleUnitAddress, SLOT(unitRibbonPressSlot()));
    
    connect(ui->UnitList, SIGNAL(itemClicked(exampleItemAddress)), exampleUnitAddress, SLOT(unitRibbonPressSlot()) );
    

    ExampleButton (a QPushButton on the ui) successfully opens the unit's window, however pressing on the Ribbon for the example Unit does not.


  • Qt Champions 2017

    Hi
    When using the old SLOT and SIGNAl macros, you should always
    check the return value of connect.
    Also you seem to mix signatures/odd syntax
    connect(ui->UnitList, SIGNAL(itemClicked(exampleItemAddress)), exampleUnitAddress, SLOT(unitRibbonPressSlot()) );
    What is exampleItemAddress ?
    and unitRibbonPressSlot should also accept such paramter
    Are you sure that UnitLists signal itemClicked have that signature ?



  • void itemClicked(QListWidgetItem *item)

    can you explain your response more please?

    It takes in the item instanced above (and shown in the list) and has no return



  • What do you mean by the 'old' signal and slot macros?



  • Ah I see, the signals are only allowed to be passed parameter types, not names, so how do I link the specific item clicked on to it's specific unit's window?


  • Qt Champions 2017

    @Hubbard
    Hi
    Yes for connect, you only list the type and not the parameter name.

    The actual parameter is added by the widget that emit the signal.
    ( in this case when you click something)

    Normally, the SLOT should accept the same paramter(s)

    by old i mean
    https://wiki.qt.io/New_Signal_Slot_Syntax
    Its possible to use other syntax that fails at compile time.
    The price is a ugly syntax if there are overloaded signals ( one send index, other send string as example)



  • @mrjj
    Could you explain what you meant about the actual parameter is passed by the item that's emits the signal please

    How could I use this to open a different window for a different item?


  • Moderators

    @Hubbard Please read http://doc.qt.io/qt-5/signalsandslots.html
    Parameters are not passed at the time you connect a slot to a signal (how would it be possible?), but at the time the signal is emitted. So, the object emitting the signal passes the parameter.
    For example lets say you have a class with void someSignal(int someParameter) signal, then an instance of this class would emit the signal like this:

    emit someSignal(10);
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.