You are not logged in.

1

Saturday, November 19th 2011, 11:59pm

returning row's number after clicking QPushButton

Hello :D , I'm new in this forum as in Qt and this is my first post, so I'm hoping someone can help me solve my "little" problem.

I've created a QTablewidget with some items, and a "usun2" button on the end of each row. Now i need to return the number of row in which the "Delete" button was clicked so i can use it in another function. This is what I was able to do, but this only returns me the row count number:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
int Manager::pokazSlot()
{
	int b=0;
	QPushButton *usun = new QPushButton("Usun zaznaczone");
	usun->setParent(tabela);
	// QTableWidget *tabela; is declared in the mainwindow.h file
 	tabela->setColumnCount(3);
	tabela->setColumnWidth(2,100);
 	tabela->setWindowTitle("Wszystkie terminy");
	QStringList kolumny;
        kolumny << "Data" << "Tresc" << "Usun zaznaczone" ;
	tabela->setHorizontalHeaderLabels(kolumny);
	QDate today = QDate::currentDate();
	int i;
	QPushButton *usun2;

	for (i=-4000;i<4000;i++)
	{
		QDate all = today.addDays(i);
		if(QFile::exists(all.toString() + ".txt"))
		{
			QCheckBox *chkBox = new QCheckBox;
			usun2 = new QPushButton("Delete",this);
			tabela->setRowCount(b+1);
			QFile file(all.toString() + ".txt");

			QTableWidgetItem *data = new QTableWidgetItem;
			data->setText(all.toString());
			tabela->setItem(b,0,data);
			if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
			return 0;

			QTextStream in(&file);
			QTableWidgetItem *tresc = new QTableWidgetItem;
			tresc->setText(in.readAll());
			tabela->setItem(b,1,tresc);
			tabela->setCellWidget(b,2,usun2);
			tabela->item(b,0)->setCheckState(chkBox->checkState());
			tabela->resizeColumnToContents(1);
			tabela->resizeColumnToContents(0);
			tabela->resizeRowToContents(b);
			connect(usun,SIGNAL(clicked()),this,SLOT(usunSlot()));
			connect(usun2,SIGNAL(clicked()),this,SLOT(usunPozycje()));
			b++;
		}
  	}

    int szer = tabela->columnWidth(0)+tabela->columnWidth(1)+17;
usun->setAutoDefault(false);usun->move(szer,0);
tabela->setFixedSize(tabela->horizontalHeader()->length() + 60, tabela->verticalHeader()->length() + 60);
tabela->show();
return b;

void Manager::usunPozycje()
{
	//int indeks; declared in mainwindow.h file
	index = Manager::pokazSlot();
	QMessageBox::StandardButton czyszczenie;
	czyszczenie = QMessageBox::warning(this, tr("Manager"),
	tr("Do you want to delete file  %1?").arg(index),
	QMessageBox::Yes | QMessageBox::Cancel);
}



So, can anyone help me solve my problem? I don't have any more ideas how to pass to "indeks" number of the row in which the "usun2" button was clicked

2

Sunday, November 20th 2011, 11:08am

do you know about Qbuttongroup? That will no doubt help a lot.

http://doc.qt.nokia.com/stable/qbuttongroup.html
In addition, QButtonGroup can map between integers and buttons. You can assign an integer id to a button with setId(), and retrieve it with id(). The id of the currently checked button is available with checkedId(), and there is an overloaded signal buttonClicked() which emits the id of the button.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

slevon

Trainee

Posts: 89

Location: Germany

Occupation: electrical engineer

  • Send private message

3

Sunday, November 20th 2011, 11:10am

Hi,
so my first approach would be to have a QList of QPushbutton-Pointers, which is visible to your whole class.
Put this in your class

Source code

1
QList<QPushbutton*> delButtons;

The lines in you for loop would be like:

Source code

1
2
3
4
5
6
7
8
9
TODO: free the memory of the allocated items

delButtons.clear();//make sure to clear this list
...
QCheckBox *chkBox = new QCheckBox;
usun2 = new QPushButton("Delete",this);
delButtons.append(usun2);         //fill your list
tabela->setRowCount(b+1);
...

So, this creates you a list of pointers to the buttons.
In your called slot you can determine the sender object using:

Source code

1
int row=delButtons.indexOf(sender());  //gives you the row (which is index of the list)

I did not check the code. It might be erroneous.
But this will not work with your strange for loop, so you might change it to

Source code

1
2
3
...
for (i=0;i<8000;i++)
...


Hope this helps,
slevon

4

Sunday, November 20th 2011, 11:17am

I disagree with the method above (slevon). You've got a container, which is not necessary, and you've also got an order N lookup every time a button is clicked. All this could be avoided.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

slevon

Trainee

Posts: 89

Location: Germany

Occupation: electrical engineer

  • Send private message

5

Sunday, November 20th 2011, 11:19am

Ups,
Amleto had been faster (2min :-) ).
But he is even more right than I am.
I would recommend his solution, too.

Best wishes,
slevon

slevon

Trainee

Posts: 89

Location: Germany

Occupation: electrical engineer

  • Send private message

6

Sunday, November 20th 2011, 11:20am

Yes Amleto,
you are right. You wrote your answer while I was writing mine. (2min faster again)

slevon

This post has been edited 1 times, last edit by "slevon" (Nov 20th 2011, 11:29am)


7

Sunday, November 20th 2011, 1:56pm

"do you know about Qbuttongroup? That will no doubt help a lot.

http://doc.qt.nokia.com/stable/qbuttongroup.html
In addition, QButtonGroup can map between integers and buttons. You can assign an integer id to a button with setId(), and retrieve it with id(). The id of the currently checked button is available with checkedId(), and there is an overloaded signal buttonClicked() which emits the id of the button."

Ok, so I've created a QButtonGroup in my mainwindow.h file called QButtonGroup *guziki;
and
guziki = new QButtonGroup; in my Manager::pokazSlot function.

Then in every loop cycle I've added a button guziki->addButton(usun2,b); where b is the row's number.
I've tried connect(guziki->button(b),SIGNAL(clicked()),this,SLOT(usunPozycje()));
and after attempting to give indeks value indeks = guziki->checkedId(); i always get -1, like that button did't exist at all.

Can you give me an example how to pass this Id to my usunPozycje function?

Here's my present code:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
int Manager::pokazSlot()
{
    int b=0;
    int i;

    QPushButton *usun = new QPushButton("Usun zaznaczone");
    QStringList kolumny;
    QDate today = QDate::currentDate();
    QPushButton *usun2;
    guziki = new QButtonGroup;

    usun->setParent(tabela);
    tabela->setColumnCount(3);
    tabela->setColumnWidth(2,100);
    tabela->setWindowTitle("Wszystkie terminy");   
    kolumny << "Data" << "Tresc" << "Usun zaznaczone" ;
    tabela->setHorizontalHeaderLabels(kolumny);

    for (i=-4000;i<4000;i++)
    {
        QDate all = today.addDays(i);
        if(QFile::exists(all.toString() + ".txt"))
            {
                tabela->setRowCount(b+1);

                QCheckBox *chkBox = new QCheckBox;
                usun2 = new QPushButton("Delete",this);

                QFile file(all.toString() + ".txt");


            QTableWidgetItem *data = new QTableWidgetItem;
            data->setText(all.toString());
            tabela->setItem(b,0,data);
            if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
             return 0;

            QTextStream in(&file);
            QTableWidgetItem *tresc = new QTableWidgetItem;
            tresc->setText(in.readAll());
            tabela->setItem(b,1,tresc);
            guziki->addButton(usun2,b);
            tabela->setCellWidget(b,2,guziki->button(b));
            tabela->item(b,0)->setCheckState(chkBox->checkState());
            tabela->resizeColumnToContents(1);
            tabela->resizeColumnToContents(0);
            tabela->resizeRowToContents(b);
            connect(usun,SIGNAL(clicked()),this,SLOT(usunSlot()));
            connect(guziki->button(b),SIGNAL(clicked()),this,SLOT(usunPozycje()));

            b++;

            }     
    }

    int szer = tabela->columnWidth(0)+tabela->columnWidth(1)+17;
    usun->setAutoDefault(false);
    usun->move(szer,0);
    tabela->setFixedSize(tabela->horizontalHeader()->length() + 60, tabela->verticalHeader()->length() + 60);
    tabela->show();
        
return b;
}

void Manager::usunPozycje()
{
indeks = guziki->checkedId();
    //indeks = Manager::pokazSlot();
    QMessageBox::StandardButton czyszczenie;
    czyszczenie = QMessageBox::warning(this, tr("Manager"), //wyswietl komunikat o niezapisanych zmianach w dokumencie
                 tr("Czy napewno skasowac %1?").arg(indeks),
                QMessageBox::Yes | QMessageBox::Cancel);
}


Btw thanks for help, you guys are great :)

8

Sunday, November 20th 2011, 2:15pm

Hi,
checkedId() only works if your buttons are checkable and exclusive (I think), so that shouldn't apply here.

You should look a the button group signals, like void buttonClicked ( int id ). You can connect that to a slot you make, and then you already have the row number.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

9

Sunday, November 20th 2011, 2:21pm

Ok, I've connected it like this

connect(guziki,SIGNAL(buttonClicked(int b)),this,SLOT(usunPozycje())); where b is the rows number.

and I have message:
Object::connect: No such signal QButtonGroup::buttonClicked(b) in mainwindow.cpp:174


Now how do I use this variable b in my usunPozycje function and what's wrong with my connection?

This post has been edited 1 times, last edit by "Rodzu" (Nov 20th 2011, 2:43pm)


10

Sunday, November 20th 2011, 4:06pm

because thats not how you connect signals slots. Also, what is the point in connecting that signal, with information you want/need, to a slot where you ignore the info??

Do this:
connect(guziki,SIGNAL(buttonClicked(int)),this,SLOT(some_slot(int)));


Obviously you need to refactor your slot slightly.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

This post has been edited 1 times, last edit by "Amleto" (Nov 20th 2011, 5:56pm) with the following reason: wrote signal, meant slot


11

Sunday, November 20th 2011, 4:35pm

Thanks a lot :) Now I've got what I needed :) You guys are really great :) I think that this tread can be closed now :) One again thank You very much :)