0

I have run into a problem with my program which I don't know how to solve. The problem is I have a Qtablewidget in two classes, and I have used the signal and slot mechanism to transfer a QVector, which contains the QTablewidgetItems from one class, and place it in the other classes QTableWidget. The problem I'm getting is that when I press the transfer button on one class, no data is transferred. Can anyone tell me what the problem is? cause i'm stumped. Code Below:

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "editmode1.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:   
explicit MainWindow(QWidget *parent = 0);


~MainWindow();
protected:
    Ui::MainWindow *ui;
public slots:
void setTableDataSlot(int width, int height, QVector<QTableWidgetItem*>const& EditData);

private slots:

void on_actionEdit_Mode_triggered();

private:
EditMode1 *mEdit;
};

#endif // MAINWINDOW_H

EditMode1.h:

#ifndef EDITMODE1_H
#define EDITMODE1_H

#include <QDialog>
#include <QTableWidget>

namespace Ui {
class EditMode1;
}

class EditMode1 : public QDialog
{
Q_OBJECT

public:
explicit EditMode1(QWidget *parent = 0);

~EditMode1();
signals:
void setTableDataSignal(int width, int height, QVector<QTableWidgetItem*> const& EditData)

private slots:

void on_buttonBox_accepted();

void on_buttonBox_rejected();

private:
Ui::EditMode1 *Editui;


};

#endif // EDITMODE1_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QCoreApplication>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{

ui->setupUi(this);
ui->tableWidget->setRowCount(6);         
ui->tableWidget->setColumnCount(5);      
for(int i = 0;i<ui->tableWidget->rowCount();++i){
    for(int j = 0;j<ui->tableWidget->columnCount();++j){
        QTableWidgetItem *tableitem = new QTableWidgetItem(" ");
        ui->tableWidget->setItem(i,j,tableitem);
    }
  }
}
MainWindow::~MainWindow()
{

}

void MainWindow::on_actionEdit_Mode_triggered()
{
mEdit = new EditMode1(this);
connect(mEdit,SIGNAL (setTableDataSignal(int width, int height, QVector<QTableWidgetItem*> const& EditData)),this,
                  SLOT(setTableDataSlot(int width, int height,QVector<QTableWidgetItem*>const& EditData)));
mEdit->show(); 
}

void MainWindow::setTableDataSlot(int width, int height,QVector<QTableWidgetItem*>const& EditData){
     for(int i = 0; i<height;++i){
      for(int j = 0; j<width;++j){

        QTableWidgetItem* copieditem = new QTableWidgetItem( *EditData[i*height + j]) ;
        ui->tableWidget->setItem(i,j,copieditem);
        }
    }
}

EditMode1.cpp:

#include "ui_mainwindow.h"
#include "mainwindow.h"
#include "editmode1.h"
#include "ui_editmode1.h"


int rows = 6;
int columns = 5;

EditMode1::EditMode1(QWidget *parent) :
QDialog(parent),
Editui(new Ui::EditMode1)
{
Editui->setupUi(this); 
 for (int i=0; i<rows;++i){
    for(int j = 0; j<columns;++j){
        QTableWidgetItem *blankitem = new QTableWidgetItem("  ");
        Editui->tableWidget->setItem(i,j,blankitem);
    }
 }
}

EditMode1::~EditMode1()
{
delete Editui;
}

void EditMode1::on_buttonBox_accepted()
{
QVector <QTableWidgetItem*> AllItems; 
for (int i=0; i<rows;++i){
    for(int j = 0; j<columns;++j){
        AllItems.push_back(Editui->tableWidget->item(i,j)); 
   }
 }
emit setTableDataSignal(columns,rows,AllItems);
}

void EditMode1::on_buttonBox_rejected()
{
reject();
}

Sorry about there being a lot of code, but I don't know what part of the program is causing it to produce nothing, and I thought with all code on display it would be easier for others to debug. Thanks in advance!

Kitty Burner
  • 47
  • 11
  • The `emit setTableDataSignal(AllItems)`should be after the for loops. – Thomas Apr 05 '16 at 18:51
  • And you should `append` or `push_back` items instead of accesing an invalid position with `[p]`, and why `p`? you write to the same invalid pos several times. – Thomas Apr 05 '16 at 18:54
  • Of course how could I be so dumb. I think I was trying to append the items to the vector in a quick fashion (dumb because I was doing it completely wrong) thank you so much for your help. However, now when I try transferring the data I get the error "QTableWidget: cannot insert an item that is already owned by another QTableWidget". I'm probably being dumb again but, how does one solve this? – Kitty Burner Apr 05 '16 at 19:10
  • Maybe save the data of the table item and create a new item from the data in the receiving table? – Thomas Apr 05 '16 at 19:15
  • tried this with the line `"QTableWidgetItem* copieditem = new QTableWidgetItem(EditData[p]);` and it kept saying invalid conversion from "QTableWidgetItem*" to "int". This makes no sense because i'm not trying to convert to an integer. (I have updated the full code in my question incase you wanted to see it in full, thanks for the help by the way!). – Kitty Burner Apr 05 '16 at 19:30
  • That's because it thinks you're trying to call `QTableWidgetItem(int type = Type)`. You have to dereference the pointer as in `QTableWidgetItem( *EditData[p] )`, – Thomas Apr 05 '16 at 20:05
  • jackpot. But this is coding and the errors never stop, now it only transfers the last item on the first `QTableWidget` to all the items on the second `QTableWidget`. I have no idea why, the `QVector` should fix this problem but apparently not. – Kitty Burner Apr 05 '16 at 20:11

1 Answers1

1

You probably want to signal the region dimensions with the data, so the signal should be something like:

signals:
void setTableDataSignal( 
    int width, int height, const QVector<QTableWidgetItem*>& EditData);

To send the signal try:

void EditMode1::on_buttonBox_accepted()
{
    QVector <QTableWidgetItem*> AllItems;
    for (int y = 0; y < rows; ++y )
    {
        for( int x = 0; x < columns; ++x )
        {
            AllItems.push_back( Editui->tableWidget->item(x,y) );
        }
    }

    emit setTableDataSignal( columns, rows, AllItems );
}

In the receiving widget, you should then do something like:

void MainWindow::setTableDataSlot( 
    int width, int height, const QVector<QTableWidgetItem*>& EditData)
{
    for(int y = 0; y < height; ++y)
    {
        for(int x = 0; x < width; ++x)
        {
            QTableWidgetItem* copieditem = new QTableWidgetItem( *EditData[y*height + x]) ;
            ui->tableWidget->setItem( x, y, copieditem );
        }
    }
}
Thomas
  • 4,980
  • 2
  • 15
  • 30
  • ok, thanks this is great help, for now and the future. so now i run the program, it works fine until I try transfer, where it then says there is no signal named such and such, so then I changed the signal and slot to the correct version and it still says there is no signal named `setTableDataSignal(int width, int height, QVector const& EditData)`, Which is a lie because I made sure there was..... what is my problem? (thank you by the way, without you I wouldn't of made progress today and you have been a massive help!!) – Kitty Burner Apr 05 '16 at 21:13
  • updated the questions code for you to take a look at. – Kitty Burner Apr 05 '16 at 21:24
  • You onyl place the signature on the connect, `connect(mEdit,SIGNAL(setTableDataSignal(int,int,const QVector &)),this, SLOT(setTableDataSlot(int,int,const QVector&)));` without the names and Qt wants the const before the type. – Thomas Apr 05 '16 at 22:23
  • You shouldn't keep editing your code or the comments answers stop making sense. – Thomas Apr 05 '16 at 22:28
  • Oh ok thanks. Well even with the above peice of code, it gives me the error `ASSERT failure in QVector::operator[]: "index out of range", file C:\Qt\5.5\mingw492_32\include/QtCore/qvector.h, line 397`. Does this mean its gone beyond the vectors limits? is there a way to stop this? – Kitty Burner Apr 06 '16 at 08:26
  • should i be using a 2d vector for this application? one for rows and one for columns? – Kitty Burner Apr 06 '16 at 08:28
  • yes, that mean an index is beyond the vector limits. Possible an row / col, width / height switch somewhere. Why don't try debugging your code? 2D is a legitimate alternative.. – Thomas Apr 06 '16 at 10:38
  • when debugging, I remade the error but the debugger didn't say anything about it, so I'm not sure. I looked for where I could of switched the width/height somewhere or rows/columns but I didn't find anything that fixed the problem. Should I try a 2D vector? or shall I continue going over my code? – Kitty Burner Apr 06 '16 at 11:27
  • Ha ha I found the problem (of course I'm a bit silly), I had the rows and columns the wrong way round on the line `emit setTableDataSignal(columns, rows, AllItems );` now its `emit setTableDataSignal(rows, columns, AllItems );` which is waaay better. phew there was me thinking i may had to do a 2D vector. Thank you so much for everything, the amount of times I tried to get help for this topic was unreal and only you have helped me solve it (well I did have others inputs who helped but not as much as yours!)! So thanks very much! – Kitty Burner Apr 06 '16 at 11:32