Версия для печати темы
Форум на CrossPlatform.RU _ Qt GUI _ Маркер в таблице...
Автор: fortero 18.4.2011, 13:51
Добрый день Господа!
Есть вот такой незамысловатый код:
#include <QtGui>
#include <QtCore>
int main(int argc, char ** argv){
QApplication app(argc, argv);
QTableWidget table(2, 2);
QStringList tit;
tit << "Columens Name" << "Columens Phone";
table.setHorizontalHeaderLabels(tit);
QTableWidgetItem *item1 = new QTableWidgetItem("Vasy");
QTableWidgetItem *item2 = new QTableWidgetItem("77777777");
QTableWidgetItem *item3 = new QTableWidgetItem("Pety");
QTableWidgetItem *item5 = new QTableWidgetItem("11111111");
table.setItem(0,0, item1);
table.setItem(0,1, item2);
table.setItem(1,0, item3);
table.setItem(1,1, item5);
table.setSortingEnabled(true);
QString s =
" QHeaderView::down-arrow {"
" image: url(img/down.png); width: 18px"
" }"
" QHeaderView::up-arrow {"
" image: url(img/up.png); width: 18px"
" }";
app.setStyleSheet(s);
table.resizeRowsToContents();
table.show();
return app.exec();
}
Это простая табличка, из 2 колонок и 2 строк, сортировка работает… Вод только осталось решить 2 проблемы я не селён в QT, я только начинаю. Подскажите пожалуйста как сделать что бы когда я 1 раз кликаю на строку марке не ячейку подсвечивал а всю строку и второе разумеется не пробовал редактировать. То есть мне нужна табличка которая не будет редактироваться, а маркер подсвечивать будет всю строку, как это сделать???
Спасибо за внимание!
Автор: fortero 18.4.2011, 14:37
С первой проблемой я догадываюсь как решить нашёл я слот selectRow(int row), то есть зная на какой строке стоит маркер можно при помощи connect передать номер строки, тогда как связать эти действия? То есть как послать нужный сигнал???
Автор: fortero 18.4.2011, 15:07
Помоему я нашёл решение, скажите насколько это правильно но чёрт возми оно работает:
QObject::connect(&table, SIGNAL(cellClicked(int, int)), &table, SLOT(selectRow(int)));
Как же быть со вторым вопросом? Запрет редактирования???
Автор: wiz29 18.4.2011, 15:14
Цитата(fortero @ 18.4.2011, 15:37)
... тогда как связать эти действия? То есть как послать нужный сигнал???
Не совсем понятно о чем идет речь.
Цитата(fortero @ 18.4.2011, 16:07)
Помоему я нашёл решение, скажите насколько это правильно но чёрт возми оно работает:
QObject::connect(&table, SIGNAL(cellClicked(int, int)), &table, SLOT(selectRow(int)));
Абсолютно нормальное решение.
Цитата(fortero @ 18.4.2011, 16:07)
Запрет редактирования???
QTableWidgetItem* pItem = new QTableWidgetItem(tr("blablabla"));
pItem->setFlags(pItem->flags() & (~(Qt::ItemIsEditable)));
Автор: fortero 18.4.2011, 16:09
[quota]
QTableWidgetItem* pItem = new QTableWidgetItem(tr("blablabla"));
pItem->setFlags(pItem->flags() & (~(Qt::ItemIsEditable)));
[/quote]
А я вот ещё нашёл, подайдёт?
table.setEditTriggers(QAbstractItemView::NoEditTriggers);
Автор: wiz29 18.4.2011, 16:37
да подойдет, если нужен запрет на редактирование всего представления таблицы.
Автор: silver47 18.4.2011, 17:42
Цитата(fortero @ 18.4.2011, 13:51)
а маркер подсвечивать будет всю строку, как это сделать???
Цитата(fortero @ 18.4.2011, 17:07)
Помоему я нашёл решение, скажите насколько это правильно но чёрт возми оно работает:
Мне кажется так лучше:
QTableWidget::setSelectionBehavior(QAbstractItemView::SelectRows);
Автор: fortero 18.4.2011, 17:44
Новый вопрос, теперь решил я передовать сигнал в слот другого класса, вот таким способом:
QObject::connect(&table, SIGNAL(itemDoubleClicked(QTableWidgetItem)), &ddd, SLOT(dial(QTableWidgetItem)));
Но не чего не происходит, а когда я пробовал так:
QObject::connect(&table, SIGNAL(cellDoubleClicked(int, int)), &ddd, SLOT(dial(int, int)));
То всё работало передовался номер строки и колонки, а как же передать содиржимое ячейки?
Автор: ruzik 18.4.2011, 17:48
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //Выделить всю строку
tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //Запрет редактирования
Автор: silver47 18.4.2011, 18:10
Цитата(fortero @ 18.4.2011, 19:44)
То всё работало передовался номер строки и колонки, а как же передать содиржимое ячейки?
Ну логично предположить, что, если вы ячейку не редактируете, а просто выделяете, то нужно бы создать свой сигнал, который будет испускаться при выделении ячейки, и который будет передавать ее содержимое. Если точно не знаете, что будет в ячейке, то рекомендую в сигнале передавать тип QVariant
Для этого свяжем сигнал выделения ячейки с неким слотом:
QObject::connect(table, SIGNAL(clicked(QModelIndex)), this, SLOT(someSlot(QModelIndex)));
// слот
// берем значение ячекий
QVariant value(index.sibling(index.row(), index.column()).data(Qt::EditRole));
// испускаем сигнал со значением
emit cellValue(value);
Автор: fortero 18.4.2011, 18:24
Уже получилось передать ячейку:
MyDialog *ddd = new MyDialog;
QObject::connect(&table, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), ddd, SLOT(dial(QTableWidgetItem *)));
Вопрос следующий а как из объекта класса QTableWidgetItem извлечь данный и к примеру привратить в класс QString????
Автор: silver47 18.4.2011, 18:26
Цитата(fortero @ 18.4.2011, 20:24)
Уже получилось передать ячейку:
MyDialog *ddd = new MyDialog;
QObject::connect(&table, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), ddd, SLOT(dial(QTableWidgetItem *)));
Вопрос следующий а как из объекта класса QTableWidgetItem извлечь данный и к примеру привратить в класс QString????
Смотрите мой пост выше. А из QTableWidgetItem вы можете получить текст просто, вызвав метод QTableWidgetItem::text();
Автор: fortero 18.4.2011, 18:29
А чем плох мой способ передачи???
Автор: silver47 18.4.2011, 18:30
Цитата(fortero @ 18.4.2011, 20:29)
А чем плох мой способ передачи???
Ничем. Нормальный способ
Только, как мне кажется, он будет работать только с QTableWidget. У QTableView передать ячейку не удастся.
Автор: fortero 18.4.2011, 18:38
Всем кто участвовал огромное спасибо у меня всё получилось!!!
Автор: fortero 20.4.2011, 21:14
А ещё вопрос, а если мне надо по клавише Enter вызывать сигнал, как это организовать с клавишами я пока не работал ещё??? То есть мне нужно когда я стою на нужной строке и жму клавишу Enetr происходило действие...
Автор: silver47 21.4.2011, 5:06
Цитата(fortero @ 20.4.2011, 23:14)
А ещё вопрос, а если мне надо по клавише Enter вызывать сигнал, как это организовать с клавишами я пока не работал ещё??? То есть мне нужно когда я стою на нужной строке и жму клавишу Enetr происходило действие...
1. Изменения которые необходимо внести в заголовочный файл того виджета, на котором таблица расположена:protected:
virtual void keyPressEvent(QKeyEvent *pe);
2. Теперь создадим описанный нами метод:void Widget::keyPressEvent(QKeyEvent *pe){
if ((pe->key() == 16777220) | (pe->key() == 16777221)) this->someSlot(); // Enter
}
16777220 и 16777221 - это коды двух клавиш Enter. Чтобы узнать какой код у кнопки, поставьте вывод qDebug() << pe; в самом начале метода. Для того, чтобы знать нажаты ли кнопки-модификаторы (Alt; Ctrl; Shift), нужно проверить вот такое вот условие:
if (pe->modifiers() & Qt::ShiftModifier) // зажат шифт
if (pe->modifiers() & Qt::AltModifier) // зажат альт
if (pe->modifiers() & Qt::CtrlModifier) // зажат Ctrl
Опять же, все тот же, Макс Шлее страница 259
Автор: fortero 2.5.2011, 2:26
Цитата(silver47 @ 21.4.2011, 5:06)
Цитата(fortero @ 20.4.2011, 23:14)
А ещё вопрос, а если мне надо по клавише Enter вызывать сигнал, как это организовать с клавишами я пока не работал ещё??? То есть мне нужно когда я стою на нужной строке и жму клавишу Enetr происходило действие...
1. Изменения которые необходимо внести в заголовочный файл того виджета, на котором таблица расположена:protected:
virtual void keyPressEvent(QKeyEvent *pe);
2. Теперь создадим описанный нами метод:void Widget::keyPressEvent(QKeyEvent *pe){
if ((pe->key() == 16777220) | (pe->key() == 16777221)) this->someSlot(); // Enter
}
16777220 и 16777221 - это коды двух клавиш Enter. Чтобы узнать какой код у кнопки, поставьте вывод qDebug() << pe; в самом начале метода. Для того, чтобы знать нажаты ли кнопки-модификаторы (Alt; Ctrl; Shift), нужно проверить вот такое вот условие:
if (pe->modifiers() & Qt::ShiftModifier) // зажат шифт
if (pe->modifiers() & Qt::AltModifier) // зажат альт
if (pe->modifiers() & Qt::CtrlModifier) // зажат Ctrl
Опять же, все тот же, Макс Шлее страница 259
Спасибо, это очень интересно, но а как мне в слот передать информацию о месте нахождения маркера, когда мышей я кликал то я использовал вот такой вариант:
connect(mtab, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(dubleClic_slot(int )));
А тут как быть, как узнать отмеченный маркер, причём последний, ведь случайно можно две строки выделить!
Спасибо за внимание!
Автор: silver47 2.5.2011, 6:05
гм... Наверное будет работать тоже самое:
QModelIndex index(QTableView::curentIndex()); вместо QTableView - подставьте свою таблицу
if(!index.isValid)) return; // выход если индекс не корректен
QString Str;
Str = index.sibling(index.row(), index.column()).data(Qt::EditRole).toString(); // поместили в переменную Str текст выделенной ячейки
Автор: fortero 2.5.2011, 19:49
Одна проблема, у меня не QTableView а QTableWidget, а функций индекс там нет...
Автор: fortero 2.5.2011, 22:01
Кажеться победил:
void TableCl::keyPressEvent(QKeyEvent *pe){
if ((pe->key() == 16777220) | (pe->key() == 16777221))
{
QList<QTableWidgetItem *> *tList = new QList<QTableWidgetItem *>(mtab->selectedItems());
if(!tList->empty())
this->dubleClic_slot(tList->last()->row());
delete tList;
}
}
Silver47 покритекуйте, может что-то не так?
Автор: Алексей1153 4.5.2011, 21:00
1) волшебные цифры лучше заменить на мнемоники (Qt::Key_Return и Qt::Key_Enter)
2) new, по моему, тут не нужен (вернее, можно без кучи обойтись):
QList<QTableWidgetItem *> tList(mtab->selectedItems());
if(!tList.empty())
{
dubleClic_slot(tList.last()->row());
}
Автор: fortero 5.5.2011, 1:08
Цитата(Алексей1153 @ 4.5.2011, 21:00)
1) волшебные цифры лучше заменить на мнемоники (Qt::Key_Return и Qt::Key_Enter)
2) new, по моему, тут не нужен (вернее, можно без кучи обойтись):
QList<QTableWidgetItem *> tList(mtab->selectedItems());
if(!tList.empty())
{
dubleClic_slot(tList.last()->row());
}
А если можно поподробней о new, просто у меня не совсем ещё сформировалось понимание когда он нужен а когда нет?
Почему Вы считаете что тут он не нужен прокаментируйте пожалуйста.
Спасибо за внимание!
Автор: Алексей1153 5.5.2011, 20:42
об операторе new подробнее, чем любая книжка по C++ я рассказать не сумею. Если коротко - это работа с кучей, new выделяет память из кучи под переменную, delete возвращает. Автоматически вызываются конструктор и деструктор соответственно
В данном случае наличие new/delete совершенно необязательно, так как автоматическая локальная переменная выполнит всё то же самое. Но если хочется, можно оставить и так, как у тебя ))
Автор: fortero 6.5.2011, 3:43
Цитата(Алексей1153 @ 5.5.2011, 20:42)
об операторе new подробнее, чем любая книжка по C++ я рассказать не сумею. Если коротко - это работа с кучей, new выделяет память из кучи под переменную, delete возвращает. Автоматически вызываются конструктор и деструктор соответственно
В данном случае наличие new/delete совершенно необязательно, так как автоматическая локальная переменная выполнит всё то же самое. Но если хочется, можно оставить и так, как у тебя ))
В каких случаях Куча актуальна будет?
Я не совсем чувствую грань когда следует в QT пользоватся динамической памятью а когда нет...
Автор: Алексей1153 6.5.2011, 19:20
Цитата(fortero @ 6.5.2011, 6:43)
Я не совсем чувствую грань когда следует в QT пользоватся динамической памятью а когда нет...
речь не про Qt, а про C++ , кстати
Цитата(fortero @ 6.5.2011, 6:43)
В каких случаях Куча актуальна будет?
например, если бы был массив большого размера. Локальные переменный размещаются на стеке, а стек имеет ограниченный размер. Если стек переполнен, то программа в лучшем случае просто аварийно завершится.
Также, для массивов с изменяемым размером. Контейнеры Qt и STL тоже внутри себя используют кучу для хранения данных. По последней причине, кстати, контейнеры можно спокойно использовать как локальные переменные, так как, по сути, "локальное" тело переменной - несколько указателей и счётчиков количества элементов. А данные лежат на куче
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)