Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Маркер в таблице...
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt GUI
fortero
Добрый день Господа!
Есть вот такой незамысловатый код:
#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
С первой проблемой я догадываюсь как решить нашёл я слот selectRow(int row), то есть зная на какой строке стоит маркер можно при помощи connect передать номер строки, тогда как связать эти действия? То есть как послать нужный сигнал???
fortero
Помоему я нашёл решение, скажите насколько это правильно но чёрт возми оно работает:
QObject::connect(&table, SIGNAL(cellClicked(int, int)), &table, SLOT(selectRow(int)));


Как же быть со вторым вопросом? Запрет редактирования???
wiz29
Цитата(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
[quota]
    QTableWidgetItem* pItem = new QTableWidgetItem(tr("blablabla"));
        pItem->setFlags(pItem->flags() & (~(Qt::ItemIsEditable)));

[/quote]

А я вот ещё нашёл, подайдёт?
table.setEditTriggers(QAbstractItemView::NoEditTriggers);
wiz29
да подойдет, если нужен запрет на редактирование всего представления таблицы.
silver47
Цитата(fortero @ 18.4.2011, 13:51) *
а маркер подсвечивать будет всю строку, как это сделать???

Цитата(fortero @ 18.4.2011, 17:07) *
Помоему я нашёл решение, скажите насколько это правильно но чёрт возми оно работает:


Мне кажется так лучше:
QTableWidget::setSelectionBehavior(QAbstractItemView::SelectRows);
fortero
Новый вопрос, теперь решил я передовать сигнал в слот другого класса, вот таким способом:
QObject::connect(&table, SIGNAL(itemDoubleClicked(QTableWidgetItem)), &ddd, SLOT(dial(QTableWidgetItem)));

Но не чего не происходит, а когда я пробовал так:
QObject::connect(&table, SIGNAL(cellDoubleClicked(int, int)), &ddd, SLOT(dial(int, int)));


То всё работало передовался номер строки и колонки, а как же передать содиржимое ячейки?
ruzik
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //Выделить всю строку
tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //Запрет редактирования
silver47
Цитата(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
Уже получилось передать ячейку:
MyDialog *ddd = new MyDialog;
QObject::connect(&table, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), ddd, SLOT(dial(QTableWidgetItem *)));


Вопрос следующий а как из объекта класса QTableWidgetItem извлечь данный и к примеру привратить в класс QString????
silver47
Цитата(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
А чем плох мой способ передачи???
silver47
Цитата(fortero @ 18.4.2011, 20:29) *
А чем плох мой способ передачи???


Ничем. Нормальный способ :) Только, как мне кажется, он будет работать только с QTableWidget. У QTableView передать ячейку не удастся.
fortero
Всем кто участвовал огромное спасибо у меня всё получилось!!! :clapping:
fortero
А ещё вопрос, а если мне надо по клавише Enter вызывать сигнал, как это организовать с клавишами я пока не работал ещё??? То есть мне нужно когда я стою на нужной строке и жму клавишу Enetr происходило действие...
silver47
Цитата(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
Цитата(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
гм... Наверное будет работать тоже самое:
QModelIndex index(QTableView::curentIndex());  вместо QTableView - подставьте свою таблицу
if(!index.isValid)) return; // выход если индекс не корректен

QString Str;
Str = index.sibling(index.row(), index.column()).data(Qt::EditRole).toString(); // поместили в переменную Str текст выделенной ячейки
fortero
Одна проблема, у меня не QTableView а QTableWidget, а функций индекс там нет...
fortero
Кажеться победил:
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
1) волшебные цифры лучше заменить на мнемоники (Qt::Key_Return и Qt::Key_Enter)
2) new, по моему, тут не нужен (вернее, можно без кучи обойтись):
QList<QTableWidgetItem *>  tList(mtab->selectedItems());
if(!tList.empty())
{
    dubleClic_slot(tList.last()->row());
}
fortero
Цитата(Алексей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
об операторе new подробнее, чем любая книжка по C++ я рассказать не сумею. Если коротко - это работа с кучей, new выделяет память из кучи под переменную, delete возвращает. Автоматически вызываются конструктор и деструктор соответственно

В данном случае наличие new/delete совершенно необязательно, так как автоматическая локальная переменная выполнит всё то же самое. Но если хочется, можно оставить и так, как у тебя ))
fortero
Цитата(Алексей1153 @ 5.5.2011, 20:42) *
об операторе new подробнее, чем любая книжка по C++ я рассказать не сумею. Если коротко - это работа с кучей, new выделяет память из кучи под переменную, delete возвращает. Автоматически вызываются конструктор и деструктор соответственно

В данном случае наличие new/delete совершенно необязательно, так как автоматическая локальная переменная выполнит всё то же самое. Но если хочется, можно оставить и так, как у тебя ))


В каких случаях Куча актуальна будет?
Я не совсем чувствую грань когда следует в QT пользоватся динамической памятью а когда нет...
Алексей1153
Цитата(fortero @ 6.5.2011, 6:43) *
Я не совсем чувствую грань когда следует в QT пользоватся динамической памятью а когда нет...

речь не про Qt, а про C++ , кстати


Цитата(fortero @ 6.5.2011, 6:43) *
В каких случаях Куча актуальна будет?


например, если бы был массив большого размера. Локальные переменный размещаются на стеке, а стек имеет ограниченный размер. Если стек переполнен, то программа в лучшем случае просто аварийно завершится.
Также, для массивов с изменяемым размером. Контейнеры Qt и STL тоже внутри себя используют кучу для хранения данных. По последней причине, кстати, контейнеры можно спокойно использовать как локальные переменные, так как, по сути, "локальное" тело переменной - несколько указателей и счётчиков количества элементов. А данные лежат на куче
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.