Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QTreeWidget
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt GUI
flankerr
Qt 4.1.2
Есть дерево в узлах установлено чекбокс, так вот не получается выловить сигнал измения состояния этого чек бокса... (когда пользователь щёлкает по чекбоксу)

connect(this,SIGNAL(itemClicked( QTreeWidgetItem * item, int column )),this,SLOT(OnChangedItem( QTreeWidgetItem * item, int column ) ));
сonnect(this,SIGNAL(itemChanged( QTreeWidgetItem * item, int column ) ),this,SLOT(OnChangedItem( QTreeWidgetItem * item, int column ) ));

разумеется слот OnChangedItem( QTreeWidgetItem * item, int column ) создан.
но не отрабатывает а где грабли не вижу...
ViGOur
А как ты выставляешь чекбокс? Я просто не совсе понял, что за чекбокс... :blush:
Litkevich Yuriy
чето я про чек бокс тоже не въехал, если юзер именно чек бокс кликает дак и сигнал чекбокса ловить надо

void stateChanged ( int state )

или
void clicked ( bool checked = false )


если, конечно, я картину правильно представил.
flankerr
Есть класс унаследованный от QTreeWidget

внутри класса

создал узел
QTreeWidgetItem* pItem = new QTreeWidgetItem(this);

вставил чекбокс
pItem->setCheckState(0,Qt::Checked);
ViGOur
У меня все отрабатывает, я сделал вот так:
class CTest: public QObject
{
    Q_OBJECT

public:
    CTest(QWidget *parent = 0, Qt::WFlags flags = 0){}
    ~CTest(){}

public slots:
    void OnCheckState( QTreeWidgetItem *item, int column);
};

void CTest::OnCheckState( QTreeWidgetItem *item, int column)
{
    QMessageBox::information( 0, "info", QObject::tr( "%1- column %2").arg( item->isExpanded()).arg( column));
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTreeWidget *pTreeWidget = new QTreeWidget( 0);
    pTreeWidget->setColumnCount(2);
    QStringList headers;
    headers << QObject::tr("Subject") << QObject::tr("Default");
    pTreeWidget->setHeaderLabels( headers);

    QTreeWidgetItem *pRoot = new QTreeWidgetItem( pTreeWidget);
    pRoot->setText( 0, QObject::tr("Root"));
    
    for( int n = 0; n < 100; n++)
    {
        QTreeWidgetItem *pChild = new QTreeWidgetItem( pRoot);
        pChild->setFlags( pChild->flags() | Qt::ItemIsEditable);
        
        QString sz0 = QObject::tr( "Item %1").arg( n);
        QString sz1 = QObject::tr( "Sub item %1").arg( n);
        pChild->setText(0, sz0);
        pChild->setText(1, sz1);

        pChild->setCheckState(0,Qt::Checked);
    }

    pTreeWidget->expandItem( pRoot);
    //pTreeWidget->collapseItem( pRoot);

    CTest test;
    QObject::connect( pTreeWidget, SIGNAL(  itemChanged( QTreeWidgetItem *, int)), &test, SLOT( OnCheckState( QTreeWidgetItem *, int)));
    pTreeWidget->show();

    return a.exec();
}
Litkevich Yuriy
Я по пробывал твой пример скомпилить, линкер ругается:
build/main.o(.text+0x1c):main.cpp: undefined reference to `vtable for CTest'
build/main.o(.text+0x4c):main.cpp: undefined reference to `vtable for CTest'
build/main.o(.text+0xb33):main.cpp: undefined reference to `vtable for CTest'
build/main.o(.text+0xc4c):main.cpp: undefined reference to `vtable for CTest'
collect2: ld returned 1 exit status


хотя в файл сунул
#include <QtGui>

может че забыл, не пойму
ViGOur
Класс CTest нужно перенести в .h файл. ;)
Litkevich Yuriy
хм, а вчем принципиальная разница?
ViGOur
в moc'е. :)
Litkevich Yuriy
ХМ, НЮАНЕЦ однако, это видимо во всех случаях где макрос Q_OBJECT,
т.к. без него я делал все в одном файле.
ViGOur
Цитата(Litkevich Yuriy @ 19.2.2008, 18:42) *
однако, это видимо во всех случаях где макрос Q_OBJECT,
Угу, именно так :)
flankerr
понял почему у меня не получалось. :rolleyes:
надо было так
itemChanged ( QTreeWidgetItem *,int )
а у меня было так
itemChanged ( QTreeWidgetItem * item, int column)
flankerr
Возник другой вопрос.
Как сделать чтобы событие отрабатывало только по действию пользователя но не работало при программном изменение значения ?
ну можно конечно делать дисконект слота перед прграмным изменением а после снова делать конектЮ но может есть что более "красивое"...
Litkevich Yuriy
не все сигналы посылаются при програмном изменении состояния, плюс некоторые функции попадаются перегруженые, в которых можно флажек выставить, "не сигналить". надо справку почитать вдруг для твоего случая такая комбинация сигнала и функции setFoo() попадется.
Tonal
Зачем же дисконнект/коннект?
Есть же QObject::blockSignals
flankerr
Цитата(Tonal @ 21.2.2008, 11:11) *
Зачем же дисконнект/коннект?
Есть же QObject::blockSignals


Насколько я понимаю в этом случае блокируються все сигналы...
В этом смысле, мне думается, конект\дисконет более правильное решение т.к. изолирует только нужную часть сигналов.
flankerr
Цитата(Litkevich Yuriy @ 21.2.2008, 0:25) *
не все сигналы посылаются при програмном изменении состояния, плюс некоторые функции попадаются перегруженые, в которых можно флажек выставить, "не сигналить". надо справку почитать вдруг для твоего случая такая комбинация сигнала и функции setFoo() попадется.

На будущие учту спаисбо
но возможность выставить флаг сигналить\несигналить я не нашёл впрочем как и функции setFoo
возможно это есть начиная с 4.2
Litkevich Yuriy
Цитата(flankerr @ 21.2.2008, 14:37) *
как и функции setFoo

Foo в переводе с английского: что-то, что-нибудь и т.д.
т.е. я имел в видукакую-нибудь функцию которая устанавливает состояние чего либо, некоторые функции не приводеть к посылке сигналаов, как
например, для класса абстрактной кнопки:
Цитата
void QAbstractButton::clicked ( bool checked = false ) [signal]
Данный сигнал посылается при активизации кнопки (т.е. когда нажатая кнопка отпускается при находении указателя мыши внутри кнопки), при нажатии горячего сочетания клавиш или при вызове click() либо animateClick(). Обратите внимание: данный сигнал не посылается при вызове setDown(), setChecked() или toggle().
У тригерной кнопки свойство checked равно true если кнопка включена, или false если кнопка выключена.
См. также pressed(), released(), и toggled().


А насчет флага, похоже это моя мечта, а не действительность :)
Tonal
Цитата(flankerr @ 21.2.2008, 14:33) *
Цитата(Tonal @ 21.2.2008, 11:11) *
Зачем же дисконнект/коннект?
Есть же QObject::blockSignals

Насколько я понимаю в этом случае блокируються все сигналы...
В этом смысле, мне думается, конект\дисконет более правильное решение т.к. изолирует только нужную часть сигналов.

Если тебе действительно нужно выборочно блокировать сигналы, тогда действительно blockSignals не подходит.
Тогда либо конект\дисконет, либо выставлять какой-нибудь флажёк перед действием, а в обработчике его проверять и ничего не делать если он выставлен.

blockSignals очень хорошо подходит при первоначальном заполнении диалога данными например. Когда к событиям привязаны проверки и/или корректировки состояний других виджетов.
flankerr
кстати чего-то сразу ступил...
blockSignal можно же выборочно использовать к любому объекту в том числе к любому объкту диалога а не кдиалогу целиком.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.