0

I have a QListWidget in my MainWindow that displays a list of VideoWidgets (a custom QWidget). VideoWidget has a clickable label where on clicking the label it should delete a file and then remove the QListItem which holds the VideoWidget from the QListWidget. Here is my VideoWidget class:

VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent)
{
    ClickableLabel *smallRed = new ClickableLabel(this)
    //...
    QObject::connect(smallRed,SIGNAL(clicked()),this,SLOT(removeVideo()));
}
void VideoWidget::removeVideo(){
    //...code to remove a file
    QListWidget* list = myParent->getList();        
    QListWidgetItem* item = list->takeItem(list->currentIndex().row());
    myList->removeItemWidget(item);
}

The problem is that clicking the smallRed label will not select its item in the QListWidget which means that list->currentIndex().row() will return -1. Clicking anywhere else in the Widget does select the current item. For the code to work I currently have to first click anywhere in the VideoWidget and then click its ClickableLabel. Is there any way I can achieve the same effect with one single click on my ClickableLabel?

testus
  • 183
  • 2
  • 21
  • Need more info. What are the contents of `VideoWidget`? What does it show? – thuga Nov 12 '14 at 08:10
  • see my previous question http://stackoverflow.com/questions/26802294/how-to-create-custom-layout-for-widget/. Its pretty much a Widget that displays 4 different labels. One if them is a `ClickableLabel` – testus Nov 12 '14 at 08:13
  • I think the best option here is to use `QListView` and paint your custom widget with a custom delegate. Use [`QAbstractItemDelegate::editorEvent`](http://qt-project.org/doc/qt-5/qabstractitemdelegate.html#editorEvent) to handle mouse clicks on your remove label. You can check [this answer](http://stackoverflow.com/a/11778012/2257050) to get an idea how it can be done. Check [this example](http://kunalmaemo.blogspot.fi/2010/12/creating-custom-qitemdelegate-with.html) too. – thuga Nov 12 '14 at 09:15

1 Answers1

0

From your previous qestion, we suggested use signal and slots. For example:

for(int r=0;r<3;r++)
{
    QListWidgetItem* lwi = new QListWidgetItem;
    ui->listWidget->addItem(lwi);
    QCheckBox *check = new QCheckBox(QString("checkBox%1").arg(r));
    check->setObjectName("filepath");
    connect(check,SIGNAL(clicked()),this,SLOT(echo()));
    ui->listWidget->setItemWidget(lwi,check);
}

Slot:

void MainWindow::echo()
{
    qDebug() << sender()->objectName() << "should be remmoved";
}

It is not unique way to solve this problem, but it shows all main things, with signals and slots mechanism, objectName and sender() you can achieve all what you need.

sender() return object which send signal, you can cast it, but if you need only objectName you should not cast.

Jablonski
  • 18,083
  • 2
  • 46
  • 47
  • Doesn't that do the same thing but now I just have my slot in the MainWindow class. I think I will still have the problem that `list->currentIndex().row()` will return -1 if I don't click the widget before clicking the label. Anyway, I tried to implement your solution but I am getting the error **error: no matching function for call to 'MainWindow::connect(ClickableLabel*&, const char*, MainWindow* const, const char*)'connect(mytest->smallRed, SIGNAL(clicked()),this,SLOT(goingInside()));** See my updated question for how I'm creating my widgets. – testus Nov 11 '14 at 19:20
  • @testus Check also includes: include ClickableLabel in mainwindow, I think you forgot do this. This answer: http://stackoverflow.com/questions/15768144/qt-subclassing-and-no-matching-function-for-call-to-connect – Jablonski Nov 11 '14 at 19:51
  • Oh yes, you are right. I completly forgot the include. I was able to compile it now but when I click on the label I get **"" should be remmoved**, even when I click on the widget first – testus Nov 11 '14 at 19:54
  • @testus In your case, label is sender so it means that your label has no object name, add this name `mytest->smallRed->setObjectName("filepath");` – Jablonski Nov 11 '14 at 19:57
  • Ok, I am getting **"filepath" should be remmoved** now everytime I click on any label. I'm failing to see how this relates to my initial problem. `ui->myList->currentIndex().row()` is still giving me -1 if I click the label without having clicked the widget first – testus Nov 11 '14 at 20:01
  • 1
    @testus I teached you how to use it properly :). About your question, so it is hard to say, I remember your previous question: http://stackoverflow.com/questions/26802294/how-to-create-custom-layout-for-widget/26802461#26802461 so your widget is very complex/ It means that your app very heavy and you can't use many items(because it will be very expensive for system)So I see only next approach. I don't like it, but... Iterate throw all items in listwidget, for all item get itemWidget pointer and check is this pointer is your current widget(your sender(your label)). – Jablonski Nov 11 '14 at 20:27
  • @testus If so, then you get current listwidgetitem and you can remove it. Maybe someone will suggest something better, but to do this someone should learn all this question to get some idea about your project. Also about public variables:) http://thecodelesscode.com/case/3 – Jablonski Nov 11 '14 at 20:27
  • I think I understand your solution. You want me to compare the objectName of the widget with the objectName of the sender, correct? I agree iterating through the QListWidget and getting every widgets objectName doesn't sound very nice. I don't get why my mouse click event for clicking/selecting the item in the QListWidget gets ignored when I click on the clickableLabel. **If I somehow can tell the program that clicking on the label also means I want to select that item/widget (set it as current item) I would not have that problem.** – testus Nov 11 '14 at 21:18
  • Thanks for your help anyway. I'll leave the question unanswered for now. Maybe someone has a better solution. About the public variable I understand its bad. Just did it quickly for testing. I'll change it to a get-function that returns the clickableLabel;) – testus Nov 11 '14 at 21:20
  • @testus No, not the object name, pointer, compare pointer, because pointers are unique but objectNanes are not. It will be something like: if(sender() == widgetInIteration. I also thought about: when you click on label sendEvent of click to parent widget(emulate click) but your widget is complex and I don't sure that it will work. – Jablonski Nov 12 '14 at 04:59