Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: n4ela от Апрель 21, 2009, 01:31



Название: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: n4ela от Апрель 21, 2009, 01:31
Есть QTableWidget надо в каждой ячейки столбца создать по checkbox'y и отслеживать изменение их состояний.
На самом деле я попробовал уже много вариантов которые пришли мне в голову, но пока что не получилось.
Вот один из них
Код:
QTableWidgetItem *temp = new ::QTableWidgetItem;
temp->setCheckState(Qt::Checked);
ui->tableWidget->setItem(1,1,temp);
Чекбокс создается, но как отслеживать изменение состояние?
Я думал что что нибудь типа
Код:
connect(temp, SIGNAL(toggled(bool)), MainWindow, SLOT(close()));
Но выдает ошибку
expected primary-expression before ‘,’ token

Еще я ради интереса посмотрел как это можно сделаьт в TreeWidget'e
ui->treeWidget->topLevelItem(j)->setCheckState(2, Qt::Checked);
Но опять же как связать со слотом?

Вобще мне надо осуществить это с QTableWidget, а с TreeWidget это уже просто ради интереса.
Буду очень благодарен если кто поможет.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: registrationfedser87 от Апрель 21, 2009, 06:32
Повесь свою обработку на сигнал:
Код
C++ (Qt)
void QTableWidget::itemChanged ( QTableWidgetItem * item );
и уже в своём слоте проверяй состояние у item


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: Barmaglodd от Апрель 21, 2009, 07:36
А почему не унаследоваться от QAbstractItemModel и не проверять Qt::CheckStateRole?


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: n4ela от Апрель 21, 2009, 11:47
Я так и не понял как со слотом связать.
Ну вот есть h файл
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QtGui/QMainWindow>
#include <QtGui/QTableWidgetItem>
#include <QtGui/QMessageBox>
 
namespace Ui
{
   class MainWindow;
}
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
public:
   MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
private:
   Ui::MainWindow *ui;
   void check( QTableWidgetItem * );
 
};
 
#endif // MAINWINDOW_H
 
cpp файл.
Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent)
   : QMainWindow(parent), ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   ui->tableWidget->setColumnWidth(0,150);
   ui->tableWidget->setRowCount(2);
   QTableWidgetItem *temp = new QTableWidgetItem;
   temp->setCheckState(Qt::Checked);
   ui->tableWidget->setItem(1,1,temp);
   MainWindow::check(temp);
 
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
void MainWindow::check(QTableWidgetItem *temp)
{
   if ( temp->checkState() == Qt::Unchecked )
   QMessageBox::warning(this, QString::fromLocal8Bit("test"), QString::fromLocal8Bit("test"));
}
 

И как теперь связать чекбокс которой в QTableWidget с функцией check?


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 11:59
через QTableWidget::itemClicked.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: n4ela от Апрель 21, 2009, 12:22
Если в cpp файле в конструкторе написать
Код
C++ (Qt)
QObject::connect(ui->tableWidget, SIGNAL(itemClicked(QTableWidgetItem*)), MainWindow, SLOT(check()));
то выдаст
expected primary-expression before ‘,’ token


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 12:26
вот так попробуй
Код
C++ (Qt)
...
QObject::connect(ui->tableWidget, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(check()));
...
 
я вот че-то не понял, из предыдущих постов видно, что сигнатура check
имеет следубщий вид
Цитировать
check(QTableWidgetItem *temp)
почему в коннекте она другая?


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: n4ela от Апрель 21, 2009, 12:37
Моя ошибка, надо check(temp)
Код
C++ (Qt)
MainWindow::MainWindow(QWidget *parent)
   : QMainWindow(parent), ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   ui->tableWidget->setColumnWidth(0,150);
   ui->tableWidget->setRowCount(2);
   QTableWidgetItem *temp = new QTableWidgetItem;
   temp->setCheckState(Qt::Checked);
   ui->tableWidget->setItem(1,1,temp);
   QObject::connect(ui->tableWidget, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(check(temp)));
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
void MainWindow::check(QTableWidgetItem *temp)
{
   if ( temp->checkState() == Qt::Checked )
   QMessageBox::warning(this, QString::fromLocal8Bit("test"), QString::fromLocal8Bit("test"));
}
 
Вот так все компилируется, но почему то не реагируюте на изменение ячейки, такое ощущение что я где то не там connect вызываю.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 12:40
блин, коннект опять неправельный  ;D
надо так
Код
C++ (Qt)
QObject::connect(ui->tableWidget, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(check(QTableWidgetItem*)));
 


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: n4ela от Апрель 21, 2009, 13:03
Понимаю что уже достал. Но connect точно можно вызывать в конструкторе MainWindow
Потому что программа компилируется, но при нажатие по чекбоксу, ничего не происходит. Может в самой функции check что то не дописал? хотя если просто вызвать check то функция выполняется.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 13:06
гы, забыл сказать, у тебя в ашнике check объявлен простым методом, а не слотом.
исправь вот так
Код
C++ (Qt)
...
private slots:
   void check( QTableWidgetItem * );
...
 
PS. всегда смотри, что в консоли, обычно, если что-то не то с коннектами, то в консоли
будет соответствующая мессага.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: pastor от Апрель 21, 2009, 13:09
Имхо тут лучше ловить сигнал QTableWidget::itemChanged. При смене состояния чекбокса этот сигнал должен испуститься


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 13:10
Имхо тут лучше ловить сигнал QTableWidget::itemChanged. При смене состояния чекбокса этот сигнал должен испуститься
ага, 100%.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: n4ela от Апрель 21, 2009, 13:18
Спасибо всем большое, все получилось. :)


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: Danila_Bagrofff от Апрель 21, 2009, 15:22
а я бы создал кучу chekBox'ов
и сделал: setCellWidget
И спокойно для каждого виджета сделал connect'ы
И никаких проблем.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: pastor от Апрель 21, 2009, 15:27
а я бы создал кучу chekBox'ов
и сделал: setCellWidget
И спокойно для каждого виджета сделал connect'ы
И никаких проблем.

Проблемы есть - память. Жирновато это будет. А если у тебя таблица огромная?


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 15:30
а я бы создал кучу chekBox'ов
и сделал: setCellWidget
И спокойно для каждого виджета сделал connect'ы
И никаких проблем.
плохой подход, очень плохой.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: Danila_Bagrofff от Апрель 21, 2009, 15:38
если  нужно вставлять свои виджеты со своими свойствами и методами. То тогда придется вставлять свои виджеты.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 15:41
тогда пишут свой делегат, который будер быстрее работать чем предложенный тобой метод.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: pastor от Апрель 21, 2009, 15:43
если  нужно вставлять свои виджеты со своими свойствами и методами. То тогда придется вставлять свои виджеты.

или использовать делегаты


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: Danila_Bagrofff от Апрель 21, 2009, 15:50
с делегатами пока не работал.
Для большой таблицы лучше исользовать их?


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 21, 2009, 15:51
ага. они для этого и предназначены.  :)


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: Danila_Bagrofff от Апрель 22, 2009, 07:21
в чем их преимущество, если все равно свой виджет придется вписывать в делегат?
Это будет еще одна надстройка над своим классом...


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: spirit от Апрель 22, 2009, 08:12
в том, что делегат сам устанавливает данные в виджет, а из виджета в модель.
он занимается отрисовкой фокуса, текста, декораций, фона.
в общем читай про делегаты и про model view programming.


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: max1983 от Июль 18, 2009, 20:07
Тема гляжу прикрыта!
Будем откупоривать.
Я считаю что цели достигли не верно!
Конечно если главное было достичь то проблем нет.

И так имею схожую проблему у меня Button вместо ChekBox

Разницы почти нет.

И так у меня Qdevelop и QDesigner и QT 4.5.2 -я тока ючусь

И так я кинул на форму контрол QtableWidget

Поставил кнопку создаю программно ячейки 6х6 и программно вставляю бутоны(кнопки)

Цитировать
void MainWindowImpl::InsertControlButtonToTable()
{
   QPushButton * ButonaME  = 0;

   
      for (int j = 1; j < 6; j++)
      {
         ButonaME = new QPushButton(ConvertText("Эт Кнопка № ") + QString("%1").arg(j),tableWidget);
         tableWidget->setCellWidget(j, 5, ButonaME);
         ButonaME->setObjectName(QString("ButonaME_%l").arg(j));
         QObject::connect(ButonaME, SIGNAL(clicked()), this, SLOT(this->Mesaga()));
      }
   
   
    QMetaObject::connectSlotsByName(this);
   
   pushButton_14->setEnabled(false);
      
}

И как вы догадались слоты не работают!
Странно..
Вы спросите зачем
QMetaObject::connectSlotsByName(this);
сам не знаю - но думаю истина где-то рядом

И так почему я предполагаю что надо обычным способом ставить слоты а не перехватывать их от tableWidget
Я для эксперимента кинул кнопку на форму и подключил через дизайнер к слоту Mesaga
Потом программно вставил ее в таблицу -и о чюдо!  ;D
Кнопка реагирует на нажатия самостоятельно!  ???
Делаем вывод мы чего то не умеем
заглянув в файлик ui.H я не нашол чего -то необычного но привожу его строки касающеюся простой функциональности

Удалил все что мог..
Цитировать
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H


#include <QtGui/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QWidget *centralwidget;
    QPushButton *pushButton;
   
    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
        MainWindow->resize(786, 742);
        centralwidget = new QWidget(MainWindow);
        centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
        pushButton = new QPushButton(centralwidget);
        pushButton->setObjectName(QString::fromUtf8("pushButton"));
        pushButton->setGeometry(QRect(10, 10, 161, 23));
       

        retranslateUi(MainWindow);
        QObject::connect(pushButton, SIGNAL(clicked()), MainWindow, SLOT(Mesaga()));
        QObject::connect(tableWidget, SIGNAL(itemEntered(QTableWidgetItem*)), MainWindow, SLOT(ClikedToControls(QTableWidgetItem*)));

        toolBox->setCurrentIndex(0);


        QMetaObject::connectSlotsByName(MainWindow);
    } // setupUi

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MyWindow", 0, QApplication::UnicodeUTF8));
        pushButton->setText(QApplication::translate("MainWindow", "\320\234\320\265\321\201\320\260\320\263\320\260 \320\261\320\276\320\272\321\201 \320\270\320\267\320\262\321\200\320\260\321\211\320\265\320\275\320\270\320\265", 0, QApplication::UnicodeUTF8));
               Q_UNUSED(MainWindow);
    } // retranslateUi

};

namespace Ui {
    class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H

И вот значит так созданная кнопка работает а моим методом нет..
Короче если тут знающие люди путь ответят в чем разница.




Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: break от Июль 18, 2009, 22:28
Цитировать
SLOT(this->Mesaga())

вообще-то насколько мне изветсно "SLOT" - это макрос и так как вы написали писать нельзя...
фактически у вас не вызывается слот от кнопки не потому что она вставлена в таблицу - а потому что она неправлено связана со слотом!

А вообще с кнопками вставленными в QTableWidget проблем нет, и сигнал ловить можно от самой кнопки

Код:
QObject::connect( pButton, SIGNAL( clicked(bool) ), this, SLOT( btnSet_TTO_CanShunt_clicked(bool) ) );

m_ui.twTTO->setCellWidget( row, TTO_CAN_SHUNT_BTN_COLUMN, pButton );

Цитировать
QMetaObject::connectSlotsByName(this);
-- это вы себе нафантазировали от нежелания читать документацию...


Название: Re: QTableWidget встроить QCheckBox и связать со слотом
Отправлено: max1983 от Июль 18, 2009, 23:13
Ну я же выделил жирным  - я тока ючусь.
Спасибо большое.

Цитировать
-- это вы себе нафантазировали от нежелания читать документацию...
Тут ты прав.  ;D