crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> QTableWidget, Как програмно реализовать перетаскивание?, Типа Drag-n-Drop, но в коде.
Danila_Bagrofff
  опции профиля:
сообщение 16.4.2009, 12:07
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 14
Регистрация: 16.4.2009
Из: Нижний Новгород
Пользователь №: 690

Спасибо сказали: 0 раз(а)




Репутация:   0  


Есть проблемка: есть 3 виджета:

QTableWidget *tbl = new QTableWidget(10,10,this);
QFrame *frm = new QFrame(this);
QWidget *wdg = new QWidget(frm);

QHBoxLayout *hbl = new QHBoxLayout(frame);
hbl->insertWidget(wdg);

//затем в процессе программы
hbl->removeWidget(wdg);
wdg->setParent(tbl);
tbl->setCellWidget(0,0, wdg);


в процессе программы wdg должен перемещаться между двумя виджетами. Соответственно менять родителя. Лэаут сам тоже устанавливает виджету родителя. То есть у wgt становится родителем frm после команды insertWidget().
есть команда setParent(). Но при смене родителя она ругается.
Если мы перемещаем wdg возникает ошибка:

Цитата
X Error: BadWindow (invalid Window parameter) 3
Major opcode: 25 (X_SendEvent)
Resourse id: .....


Как тогда правильно перемещать виджет между другими?


-----------
Отделено от темы: Шуточный пример
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 16.4.2009, 13:44
Сообщение #2


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Тут проблема на самом деле в другом.
Дело в том, что один и тот же виджет перемещается между фреймом и ячейкой таблицы. В таблицу виджет устанавливается через setCellWidget.
Если заглянуть в исходники данной функции, докопаемся до следущего кода.
Раскрывающийся текст
void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)
{
    Q_D(QAbstractItemView);
    if (!d->isIndexValid(index))
        return;
    if (QWidget *oldWidget = indexWidget(index)) {
        d->removeEditor(oldWidget);
        oldWidget->deleteLater();
    }
    if (widget) {
        widget->setParent(viewport());
        d->persistent.insert(widget);
        d->addEditor(index, widget, true);
        widget->show();
        if (!d->delayedPendingLayout)
            widget->setGeometry(visualRect(index));
        dataChanged(index, index); // update the geometry
    }
}


Обратите внимание на код. Когда вставляется виджет, сначало происходит удаление старого. При этом не происходит никакой проверки.
Т.о. образом при повторном вставлении виджета в ячейку, модель ее просто удаляет.
Вобщемто недоработка на мой взгляд.

Обойти проблему можно, если только каждый раз создавать новый виджет. Что не есть хорошо. ИМХО.

Сообщение отредактировал igor_bogomolov - 16.4.2009, 14:50
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 16.4.2009, 14:11
Сообщение #3


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Litkevich Yuriy @ 16.4.2009, 15:02) *
Если нужно вставлять в ячейку, то устанавливать родителя не надо

Можно и не устанавливать самому. Родидель установтся автоматически.
Цитата
widget->setParent(viewport());

Смотри мое сообщение выше :rolleyes:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 16.4.2009, 14:53
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


igor_bogomolov, тут похоже человеку нужно не простая смена родителя, помоему речь о Перетаскивании, соответственно тему нужно разделять.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 16.4.2009, 14:56
Сообщение #5


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Судя по его коду, он делает именно смену родителя. Логику нужно менять, таким образом добиться нужного эфекта не получится.
Но тему разделить наверно стОит :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Danila_Bagrofff
  опции профиля:
сообщение 17.4.2009, 7:19
Сообщение #6


Студент
*

Группа: Новичок
Сообщений: 14
Регистрация: 16.4.2009
Из: Нижний Новгород
Пользователь №: 690

Спасибо сказали: 0 раз(а)




Репутация:   0  


Да, я хочу перенести виджет, чтобы не дублировать.

Сделал очень простой пример:
Раскрывающийся текст

DMainDialog::DMainDialog(QWidget *parent) : QDialog(parent)
{
vbl = new QVBoxLayout(this);
tbl = new QTableWidget(4,4,this);
tbl->setMinimumSize(100,100);
tbl2 = new QTableWidget(4,4,this);
tbl2->setMinimumSize(100,100);
pb = new QPushButton("push", this);
vbl->addWidget(tbl);
vbl->addWidget(tbl2);
vbl->addWidget(pb);

lbl = new QLabel("label", this);
vbl->addWidget(lbl);

connect(pb, SIGNAL(clicked()), SLOT(clickPB()));
i =0;
}

void DMainDialog::clickPB()
{
i++;
if(i%2)
tbl->setCellWidget(0,0,lbl);
else
tbl2->setCellWidget(0,0,lbl);
}


Если надо, могу скомпиленный вариант дать.
Смысл в том, что после пары перемещений лэйбл вообще пропадает!!!
И происходит ошибка сегментирования.

Это бага Qt? Нужно перед новым размещением создавать дубликат обязательно?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 17.4.2009, 8:20
Сообщение #7


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Да елы палы. Ты вообще читаешь что тебе отвечают. Я тебе вчера сразу ответил что происходит в данной ситуации.
Цитата(igor_bogomolov @ 16.4.2009, 14:44) *
Обратите внимание на код. Когда вставляется виджет, сначало происходит удаление старого. При этом не происходит никакой проверки.
Т.о. образом при повторном вставлении виджета в ячейку, модель ее просто удаляет.
Вобщемто недоработка на мой взгляд.
Читай мое сообщение выше.

Сообщение отредактировал igor_bogomolov - 17.4.2009, 9:03
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.4.2009, 9:40
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Danila_Bagrofff @ 17.4.2009, 11:19) *
Это бага Qt? Нужно перед новым размещением создавать дубликат обязательно?
дело в том, что QTableWidget, предназанчен для довольно примитивных операций над ним. Поэтому он сам удаляет свои элементы (Игорь уже и исходник класса показал)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 17.4.2009, 10:38
Сообщение #9


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Litkevich Yuriy @ 17.4.2009, 10:40) *
QTableWidget, предназанчен для довольно примитивных операций над ним. Поэтому он сам удаляет свои элементы
Вставка виджета происходит на уровне QAbstractItemView методом setIndexWidget. При этом, данный метод не является виртуальным, и переопределить его не получится.

На мой взгляд имеем недоработку(а возможно и баг), т.к. не происходит проверки вставляемого виджета с предыдущим. Предыдущий виджет просто удаляется. Видимо так сделанно из-за того, что копирование виджетов запрещено. Хотя, на мой взгляд, они должны были предусмотреть такую возможность, что бы защититься от лишних ошибок, в результаве повторного вставления одного и того же виджета в ячейку. Это с одной стороны ошибка программиста, но и недоработка библиотеки, в крайнем случае описания данного метода.

Так что можно и отрапортовать о баге, посмотрим что ответят. Как считаете, стОит?

ИМХО.

Сообщение отредактировал igor_bogomolov - 17.4.2009, 11:11
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Danila_Bagrofff
  опции профиля:
сообщение 17.4.2009, 12:32
Сообщение #10


Студент
*

Группа: Новичок
Сообщений: 14
Регистрация: 16.4.2009
Из: Нижний Новгород
Пользователь №: 690

Спасибо сказали: 0 раз(а)




Репутация:   0  


igor_bogomolov, вы уж извините =) Просто я искал разные пути решения =) И игрался по-всякому, стараясь как-нить обойти =) не получилось.


В итоге, создаю копию нужного мне виджета и уже его размещаю. Увы, видимо, иначе пока сделать нельзя.
Спасибо =)

И не ругайтесь сильно =) не каждый раз натыкаешься на бажки кутэ =)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 24.11.2024, 22:30