Is there a Qt Dialog or Widget to interactively sort a string list?

不打扰是莪最后的温柔 提交于 2019-12-11 08:07:59

问题


I need to provide a reordering Dialog to let a user interactively order a list of strings. Does Qt already provide something fitting for this purpose?

I have searched the usual forums and examples but found nothing appropriate.

To clarify what I need:

Raw List:

  1. FileBaz
  2. FileFoo
  3. FileBar

User sorted list

  1. FileBar
  2. FileFoo
  3. FileBaz

So an arbitrary order as for example needed for merging formerly selected pdf files


回答1:


Qt already supports it, there's nothing for you to do: The standard views automatically support internal drag and drop, where items are moved around to change the order in which they are displayed.

Further quoting the documentation:

  • To enable item dragging, set the view's dragEnabled property to true.
  • To allow the user to drop both internal or external items within the view, set the view's viewport()'s acceptDrops property to true.
  • To show the user where the item currently being dragged will be placed if dropped, set the view's showDropIndicator property. This provides the user with continuously updating information about item placement within the view.
  • To enable the user to move the items around within the view, we must set the list widget's dragDropMode to QAbstractItemView::InternalMove.

Below is a sscce that you can run to see it in action.

#include <QApplication>
#include <QListWidget>
#include <QListWidgetItem>

int main(int argc, char ** argv)
{
    QApplication a(argc, argv);
    QListWidget w;
    w.addItem("Rosalind");
    w.addItem("Celia");
    w.addItem("Adam");
    w.addItem("Jaques");
    w.setDragEnabled(true);
    w.setDropIndicatorShown(true);
    w.setDragDropMode(QAbstractItemView::InternalMove);
    w.show();
    return a.exec();
}



回答2:


Not that I know of. Something simple with a Move up button and a Move down button in coordination with a QListWidget may be useful, however. Up and Down would move around the list items in the respective direction, naturally.

Even easier, in my opinion, would be to use a QTreeWidget, as, if I recall correctly, there are some easy functions for swapping items around. A combination of something like

void insertTopLevelItem ( int index, QTreeWidgetItem * item )
QTreeWidgetItem *itemAbove ( const QTreeWidgetItem * item )
QTreeWidgetItem *itemBelow ( const QTreeWidgetItem * item ) 
QTreeWidgetItem *currentItem ()
int indexOfTopLevelItem ( QTreeWidgetItem * item )

may be useful. (Excerpts from http://qt-project.org/doc/qt-4.8/QTreeWidget.html)

Edit: I haven't used QListWidget much, but seems fairly similar to the QTreeWidget in terms of ease of swapping items around. Either one works.




回答3:


Just for completeness sake: Here is the solution I'm using in the end:

#include <QtGui>

class SortDialog:public QDialog{
    Q_OBJECT
  public:
    SortDialog(QStringList* pList, QString const& title,  QString const& middleButton);
    int getSelectedItem() const;

  private slots:
    void slotAccept();
    void slotItemUp();
    void slotItemDown();
    void slotSelectItem();

  private:
    QStringList* mpList;
    QListWidget* mpListWidget;
    int mSelectedItem;

};


SortDialog::SortDialog(QStringList* pList, QString const& title,  QString const& middleButton):
  QDialog(),
  mpList(pList),
  mpListWidget(new QListWidget()),
  mSelectedItem(-1){
  this->setWindowTitle(title);

  QHBoxLayout* pMainLayout = new QHBoxLayout();
  this->setLayout(pMainLayout);

  QVBoxLayout* pListLayout = new QVBoxLayout();
  pMainLayout->addLayout(pListLayout);

  pListLayout->addWidget(mpListWidget);
  mpListWidget->setDragEnabled(true);
  mpListWidget->setDropIndicatorShown(true);
  mpListWidget->setDragDropMode(QAbstractItemView::InternalMove);

  boostForeach(QString const& string, *mpList) {
    mpListWidget->addItem(string);
  }
  mpListWidget->setMinimumWidth(mpListWidget->sizeHintForColumn(0)+10);
  mpListWidget->adjustSize();

  mpList->clear();

  QPushButton* confirm = new QPushButton(tr("Confirm"));
  connect(confirm, SIGNAL(clicked()), this, SLOT(slotAccept()));
  pListLayout->addWidget(confirm);
  confirm->setDefault(true);

  QVBoxLayout* pUpDownLayout = new QVBoxLayout();
  pMainLayout->addLayout(pUpDownLayout);

  QPushButton* up = new QPushButton(tr("Up"));
  connect(up, SIGNAL(clicked()), this, SLOT(slotItemUp()));
  pUpDownLayout->addWidget(up);

  QPushButton* down = new QPushButton(tr("Down"));
  connect(down, SIGNAL(clicked()), this, SLOT(slotItemDown()));
  pUpDownLayout->addWidget(down);

  QPushButton* ground = new QPushButton(middleButton);
  connect(ground, SIGNAL(clicked()), this, SLOT(slotSelectItem()));
  pUpDownLayout->addWidget(ground);

  this->adjustSize();
}

int SortDialog::getSelectedItem() const{
  return mSelectedItem;
}


void SortDialog::slotAccept(){
  int count = mpListWidget->count();
  for(int index = 0; index < count; index++){
    QListWidgetItem * item = mpListWidget->item(index);
    mpList->push_back(item->text());
  }

  this->close();
}

void SortDialog::slotItemUp(){
  int row = mpListWidget->currentRow();
  if(row>0){
    QListWidgetItem* pTemp = mpListWidget->takeItem(row);
    mpListWidget->insertItem(row-1,pTemp);
    mpListWidget->setCurrentRow(row-1);
  }
}

void SortDialog::slotItemDown(){
  int row = mpListWidget->currentRow();
  if(row<mpListWidget->count()-1){
    QListWidgetItem* pTemp = mpListWidget->takeItem(row);
    mpListWidget->insertItem(row+1,pTemp);
    mpListWidget->setCurrentRow(row+1);
  }
}

void SortDialog::slotSelectItem(){
  int count = mpListWidget->count();
  for(int index = 0; index < count; index++){
    QListWidgetItem * item = mpListWidget->item(index);
    QFont font = item->font();
    font.setBold(false);
    item->setFont(font);
  }

  mSelectedItem =mpListWidget->currentRow();
  qDebug() << mSelectedItem;
  QListWidgetItem* pTemp = mpListWidget->currentItem();
  QFont font = pTemp->font();
  font.setBold(true);
  pTemp->setFont(font);
}


来源:https://stackoverflow.com/questions/11216600/is-there-a-qt-dialog-or-widget-to-interactively-sort-a-string-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!