Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Select multiple widget in layout



  • I need to select multiple widgets at the same time in a layout. My program actually uses flowlayout but this QGridLayout example demonstrates the problem. I created a QListWidget to try to get QAbstractItemView::ExtendedSelection functionality but that doesn't work and instead causes the QScrollArea to not work.

    How can I select multiple widgets at the same time in a layout?

    Thanks!
    - Howard

    // listtest.cpp
    #include <QApplication>
    #include <QPushButton>
    #include <QScrollArea>
    #include <QGridLayout>
    #include <QListWidget>
    #include <QMdiArea>
    #include <QMdiSubWindow>
    
    #include "listtest.h"
    
    MainWindow::MainWindow(int argc) {
      QMdiArea* mdiArea = new QMdiArea;
      mdiArea->setFixedSize(500,600);
      setCentralWidget(mdiArea);
    
      QScrollArea* area = new QScrollArea;
      area->setWidgetResizable(true);
    
      QGridLayout* layout = new QGridLayout();
    
      if (argc == 1) {
        QListWidget* client = new QListWidget;
        client->setSelectionMode(QAbstractItemView::ExtendedSelection);
        area->setWidget(client);    
        client->setLayout(layout);
      } else {
        QWidget* client = new QWidget;
        area->setWidget(client);    
        client->setLayout(layout);
      }
    
      for (int i=0; i<200; ++i) {
        char buffer[20];
        sprintf(buffer, "  %d  ", i);
        QPushButton* button = new QPushButton(buffer);
        button->setFixedSize(50, 20);
        button->setStyleSheet("QPushButton:focus { background-color: DarkGray; }");
        layout->addWidget(button, i/5, i%5);
        if (i == 1)
          button->setFocus();
      }
    
      QMdiSubWindow* subWindow = mdiArea->addSubWindow(area);
      subWindow->setAttribute(Qt::WA_DeleteOnClose);
      subWindow->showMaximized();
    
      subWindow->show();
    }
    
    int main(int argc, char *argv[]) {
      QApplication app(argc, argv);
      MainWindow mainWin(argc);
      mainWin.show();
      return app.exec();
    }
    
    // listtest.h
    #include <QtGui>
    #include <QMainWindow>
    class QMdiArea;
    
    class MainWindow : public QMainWindow {
      Q_OBJECT
    public:
      MainWindow(int argc);
    private:
      QMdiArea* mdiArea;
    };
    
    # This was tested with QMake 3.1 and QT 5.9.5
    qmake -project "QT += widgets" "QT += printsupport" "CONFIG += debug"
    qmake
    make
    

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    What is your exact purpose with these multiple selection ?

    As for your code sample, it currently is wrong on several levels. The first being that QListWidget selection has nothing to do with widgets you might want to put in it the way your currently do.



  • Hi @SGaist,
    You asked "What is your exact purpose with these multiple selection ?"

    Thanks for the quick reply.

    I've written an image viewer with an MDI scrolling flowlayout based catalog of images that appear as a grid of 128x128 thumbnails. I need to select multiple to make it easy to delete multiple disk image files in a single operation.

    H.

    Screenshot at 2019-10-02 12-07-38.png


  • Lifetime Qt Champion

    Then it would make more sense to use a QListView with possibly a QFileSystemModel for listing the images.


  • Lifetime Qt Champion

    QListView

    and maybe set it in icon mode
    https://doc.qt.io/qt-5/qlistview.html#ViewMode-enum
    as it then would be a grid of selectable items.



  • Will QListView support a 2D grid of icons?


  • Lifetime Qt Champion

    @Howard

    Hi
    yes when viewmode is set to icon mode, its like
    a 2d grid.



  • I said "Will QListView support a 2D grid of icons?"

    @mrjj said "yes when viewmode is set to icon mode, its like
    a 2d grid"

    I haven't been able to make that happen. I can make the QListView show only one row at a time. What am I missing?

    ac0acd61-fc45-48fb-9a70-f45f1e3562b5-image.png

    // listview.cpp
    #include "listview.h"
    #include <QListView>
    #include <QStandardItemModel>
    #include <QApplication>
    
    widget::widget(QWidget *parent) : QWidget( parent ) {
      setFixedSize(300,200);
      int nrow = 4,
          ncol = 3;
    
      QStandardItemModel *model = new QStandardItemModel(nrow, ncol, this);
      for (int c=0; c<ncol; ++c) { // fill model value
        for(int r=0; r<nrow; r++) {
          QString sstr = "[ " + QString::number(c) + "," + QString::number(r) + " ]";
          QStandardItem* item = new QStandardItem(sstr);
          model->setItem(r, c, item);
        }
      }
    
      QListView* listView = new QListView(this);
      listView->setViewMode(QListView::IconMode);
      listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
      listView->setModel(model);
      //listView->setModelColumn(ncol-1);
    }
    
    int main(int argc, char *argv[]) {
      QApplication a(argc, argv);
    
      widget lve;
      lve.show();
    
      return a.exec();
    }
    
    #pragma once
    // listview.h
    #include <QWidget>
    
    class widget : public QWidget {
      Q_OBJECT
     
     public:
      widget(QWidget* parent=nullptr);
    };
    


  • @Howard said in Select multiple widget in layout:

    I haven't been able to make that happen. I can make the QListView show only one row at a time. What am I missing?

    If you add more content it is automatically adding new rows if this is your really need.


  • Lifetime Qt Champion

    Hi

    As @CKurdu says, keep on adding then its more clear :=)

    alt text

    as 128x128 with icons

    alt text

    Also, you must likely want the resizeMode to be Adjust so it will use all space available.
    and also tweak
    listView->setGridSize(QSize(132, 132));
    listView->setIconSize(QSize(128, 128));
    to make it look like you want. (icons fills all space)



  • This seems to work for a proof of concept. Before I go too much further, is this right? I'll add calls to setGridSize and setIconSize later...

    // listview.cpp
    #include "listview.h"
    #include <QListView>
    #include <QStandardItemModel>
    #include <QApplication>
    #include <QMdiArea>
    #include <QMdiSubWindow>
    
    MainWindow::MainWindow() : QMainWindow() {
      QMdiArea* mdiArea = new QMdiArea;
      setCentralWidget(mdiArea);
    
      int nrow = 4000,
          ncol = 1;
    
      QStandardItemModel *model = new QStandardItemModel(nrow, ncol, this);
      QSize itemsize(60,30);
      for(int r=0; r<nrow; r++) {
        QString sstr = "[ " + QString::number(r) + " ]";
        QStandardItem* item = new QStandardItem(sstr);
        item->setSizeHint(itemsize);
        model->setItem(r, 0, item);
      }
    
      QListView* listview = new QListView;
      listview->setViewMode(QListView::IconMode);
      listview->setSelectionMode(QAbstractItemView::ExtendedSelection);
      listview->setModel(model);
      listview->setResizeMode(QListView::Adjust);
    
      QMdiSubWindow* subWindow = mdiArea->addSubWindow(listview);
      subWindow->showMaximized();
    }
    
    int main(int argc, char *argv[]) {
      QApplication app(argc, argv);
    
      MainWindow mainWin;
      mainWin.show();
    
      return app.exec();
    }
    
    #pragma once
    // listview.h
    #include <QMainWindow>
    
    class MainWindow : public QMainWindow {
      Q_OBJECT
     
     public:
      MainWindow();
    };
    

  • Lifetime Qt Champion

    Hi
    It does look fine.
    I think you can set GridSize at any point but i didnt test it.



  • In case it might help to see my Linux image viewer, you can get its source code here:

    https://github.com/HowardRubin-dev/Thumbnal-Image-Viewer


Log in to reply