Russian Qt Forum
Ноябрь 27, 2024, 10:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Непонятка с QListWidget  (Прочитано 6567 раз)
Anarion
Гость
« : Апрель 07, 2010, 12:40 »

Здравствуйте, уважаемые программисты.
Решил реализовать диалог для возможности настройти элементов панели управления, т.е. какие QActions должны быть на QToolBar. Захотелось не просто выбирать стрелочками, а еще прикрутить Drag & Drop. Для этой цели решил использовать 2 обычных компонента QListWidget.

Код программы:
"mainwindow.h"
Код:
namespace Ui
{
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QListWidget      *lw1;
    QListWidget      *lw2;
    .......

public
  slots:
    void onUpdate(QListWidgetItem*);

private:
    Ui::MainWindow *ui;
};

"mainwindow.cpp"
Код:
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    lw1 = new QListWidget(this);
    lw2 = new QListWidget(this);

    QListWidgetItem* pitem = 0;

    lw1->setIconSize(QSize(48, 48));
    lw2->setIconSize(QSize(48, 48));

    //виджет, из которого будут "тащиться" данные
    lw1->setMovement(QListView::Static);
    lw1->setDragDropMode(QAbstractItemView::DragOnly);
    lw1->setResizeMode(QListView::Fixed);
    lw1->setDefaultDropAction(Qt::CopyAction);

    //виджет, в которы будут "тащиться" данные
    lw2->setMovement(QListView::Snap);
    lw2->setDragDropMode(QAbstractItemView::DragDrop);
    lw2->setResizeMode(QListView::Fixed);
    lw2->setDefaultDropAction(Qt::MoveAction);

    //Заполняю 4 итема виджета, Экшены писаны в дизайнере
    pitem = new QListWidgetItem(ui->actionAct1->text(), lw1);
    pitem->setIcon(ui->actionAct1->icon());
    pitem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
    lw1->addItem(pitem);

    pitem = new QListWidgetItem(ui->actionAct2->text(), lw1);
    pitem->setIcon(ui->actionAct2->icon());
    pitem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
    lw1->addItem(pitem);

    pitem = new QListWidgetItem(ui->actionAct3->text(), lw1);
    pitem->setIcon(ui->actionAct3->icon());
    pitem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
    lw1->addItem(pitem);

    spr = new QAction (QPixmap(":/Icons/Knife.png"),"Separator",ui->mainToolBar);
    pitem = new QListWidgetItem(spr->text(), lw1);
    pitem->setIcon(spr->icon());
    pitem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
    lw1->addItem(pitem);

    QSplitter *spl = new QSplitter(Qt::Horizontal,this);
    spl->addWidget(lw1);
    spl->addWidget(ui->frame);
    spl->addWidget(lw2);

    ui->hL->addWidget(spl);

    //Соединяю сигнал изменения с определенным мною слотом, для вывода инфы
    connect(lw2, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onUpdate(QListWidgetItem*)));
}

//собственно, слот, печатает количество элементов в виджете-приемнике и их названия
void MainWindow::onUpdate(QListWidgetItem* lwi)
{
  QStringList sList;
  QString S;
  for (int i=0; i<lw2->count(); i++)
  {
    //if (!sList.contains(lw2->item(i)->text(),Qt::CaseInsensitive)||(lw2->item(i)->text()=="Separator"))
      sList << lw2->item(i)->text();
      S+= lw2->item(i)->text() + "    ";
  }

  ui->textEdit->append("Num Items = " + QString::number(sList.count()));
  ui->textEdit->append("Name Items: " +S);
  ui->textEdit->append("");

Перетаскивание любого элемента из первого списка во второй происходит нормально:,

но вот дальше нечто странное: если перетащить итем из виджета wl2 собственно в него же, но в пустую область, то он(итем) после отпуская вернется в свою  позицию, при этом счетчик числа элементов в виджете увеличится до 2:
 .

 Странно, что это происходит, когда уснавлен флаг
Код:
lw2->setDefaultDropAction(Qt::MoveAction); или lw2->setDragDropMode(QAbstractItemView::InternalMove);
В этом режиме, как я вычитал, происходит перемещение, а не копирование данных. Опыты показали, что такое "размножение" происходит только 1 раз, т.е. если в виджете 3 изображенных итема, то при их перемещении всегда будет показано, что их количество 4. Да и копирование - тоже сомнительны вариант, т.к. изображается-то один всего.

Скажите пожалуйста, как можно сделать так, чтобы итем не множился, и что можно добавить, например в dropEvent виджета, чтобы получать только один, последний сигнал об изменении?

Думал о том, чтобы написать свой класс перетаскивания, но разобраться в mimeData не смог физически...

PS: Если в Qt есть компонеты, которые лучше подойдут для достжения поставленной цели, скажите пожалуйста о них. Заранее бланодарен.
Записан
Kolobok
Гость
« Ответ #1 : Апрель 07, 2010, 22:32 »

Посмотри qttoolbardialog в Qt Solutions.
Записан
Anarion
Гость
« Ответ #2 : Апрель 07, 2010, 23:43 »

Спасибо, посмотрю.

Здесь изменил:
Код:
lw2->setMovement(QListView::Snap);

на
Код:
lw2->setMovement(QListView::Static);

После этого итемы перестали множится. Потом унаследовал свой класс от QListWidget и внес следующее изменение:
Код:
void ListWidget::dropEvent(QDropEvent *event)
{
  QListWidget::dropEvent(event);
  emit doDrop(); //мой сигнал
}

После этого отсылался только 1 сигнал, что и было нужно.
Проблема решена.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 21.