PDA

View Full Version : QTableWidget Not expanding to size of QDockWidget



Caolan O'Domhnaill
20th December 2015, 00:40
Hello all,

I am running into an issue with a QTableWidget not expanding to the size of the QDockWidget it is being created inside of. I am not specifying a layout. I have tried implementing minimumSizeHint() and sizeHint() in the QTableWidget derived class. It is called once upon startup but never again when I insert columns in my table. I have tried calling it explicitly after a column insertion but it doesn't make a difference in the size. I tried force executing updateGeometry() as well, again to no avail.

This first picture shows what it looks like when my app loads. As you see the table in the "Output" is not expanded to the extent of the QDockWidget.
11580

This one shows what happens when I insert a column.
11581

How do I get this to work as I want it to?

Cheers!
-Caolan.

anda_skoa
20th December 2015, 11:09
Is the table widget the one you set with QDockWidget::setTableWidget?

Cheers,
_

Caolan O'Domhnaill
21st December 2015, 09:06
Yes it is. And it's a QTableView, not widget...



pDock = new QDockWidget(tr("Output"), this);
m_pPhysEqSolver = new PhysEqSolver(1, 2, pDock);
pDock -> setWidget(m_pPhysEqSolver);
pDock -> setAllowedAreas(Qt::BottomDockWidgetArea);
addDockWidget(Qt::BottomDockWidgetArea, pDock);




class PhysEqSolver : public QTableView {
Q_OBJECT
public:
PhysEqSolver(int rows = 0, int cols = 1, QWidget * = NULL);

anda_skoa
21st December 2015, 12:13
Hmm, ok.

Try setting the size policy of PhysEqSolver to Expanding in both directions.

Cheers,
_

Caolan O'Domhnaill
22nd December 2015, 07:32
I set the QTableWidget in the QTableView to use this: setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); I also tried Maximum in both height and width parameters and no change.

Added after 17 minutes:

Now here's something interesting, I hardcoded the size:



QSize size(640,480);
setMinimumSize(size);
setMaximumSize(size);


And it ended up looking like this. Please note that the scroll bad nolonger appears when I insert beyond the viewable area however if I undock the window and expand it beyond the 640x480 area I see the scrollbar, as I would expect it to.

So I guess the trick here then is ensuring that the size of the window is set to the area of the docked space.
11583

Added after 51 minutes:

ANyway, still not resolved as I want it to match the window size as I resize it, dock, undock, then dock again.

anda_skoa
22nd December 2015, 10:21
I set the QTableWidget in the QTableView to use this: setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); I also tried Maximum in both height and width parameters and no change.

size policy Maximum means that the size returned by the widget's sizeHint() method is the maximum size for the widget.
So the opposite of what you want.

Have you tried putting you view into a widget with a layout and setting that on the dock widget?
E.g. a QFrame so that you can see if the view doesn't resize or the frame doesn't.

Cheers,
_

Caolan O'Domhnaill
23rd December 2015, 01:52
I have given the QDockWidget a layout but it didn't work. So what you're saying then is to embed a generic QFrame inside of the QDockWidget, set a layout, then embed my QTableView inside of that? Sure that sounds daft but I'll give it a try.

Caolan O'Domhnaill
23rd December 2015, 08:11
I tried a few different things and couldn't get it to work. Would you mind pointing me to an example of what you're speaking of for me to test and play around with?

Caolan O'Domhnaill
25th December 2015, 09:31
Is there an example that points me to what you are suggesting I do? I am at a loss here.

anda_skoa
25th December 2015, 13:29
I can't really reproduce your problem.

A simple table view in a dock widget is always as big as the dock widget, using scrollbars when necessary.
11590

Cheers,
_

Caolan O'Domhnaill
28th December 2015, 07:49
Thank you!

I have reviewed the code and it seems that the only thing I am doing differently is that I am not using a model associated with the table. Does the model handle correct drawing of the window?

anda_skoa
28th December 2015, 09:19
The model is not involved in drawing, though it can provide drawing specific data such as font, color, etc.
My model doesn't do any of those though.

When you write "not using a model", how does your view get its data?

Cheers,
_

Caolan O'Domhnaill
28th December 2015, 23:40
I access the generic model from within the view as shown below. The examples I have used to get me going did not utilise the model/view architecture and since this worked as well, I kept it up as it did not prevent me from doing what I needed to.


void PhysEqSolverTable::insertColumn() {

// When inserting a new column with the default value, it should be added to the previous column
int idx = m_TimeSliceValues.count() - 1;
double newValue = m_TimeSliceValues.at(idx) + 1.0;
m_TimeSliceValues.push_back(newValue);
m_pHeader ->timeSliceList(m_TimeSliceValues);
model() ->insertColumn(model() ->columnCount());
rebuildColumnHeaders();
}

void PhysEqSolverTable::removeColumn(const int idx) {
if (model() ->columnCount() > 2) {
model() ->removeColumn(idx);
m_TimeSliceValues.removeAt(idx);
m_pHeader ->timeSliceList(m_TimeSliceValues);
rebuildColumnHeaders();
}
}

anda_skoa
29th December 2015, 09:18
A QTableView doesn't have any default model.
Is this a QTableWidget?

Cheers,
_

Caolan O'Domhnaill
29th December 2015, 23:09
The table itself yes. The View that houses it is derived from QTableView.

anda_skoa
30th December 2015, 09:16
If you don't set a model, then the model is this:
http://code.woboq.org/qt5/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp.html#QEmptyItemModel

Cheers,
_

Caolan O'Domhnaill
31st December 2015, 04:02
It seems though that I am able to work perfectly fine without using a model in conjunction with my views. Is there a compelling reason to use a model other than separatinjg data from the UI elements? I hve read the documentation on it and although I can see the benefits, and I have a plan to do the separation later after initial release, there doesn't seem to be much that is preventing me from keeping along the path I am going with this...

BTW, in relation to the original thread I have the QDockWidget containing my QTableView which contains a QTableWidget. Do you think this has anything to do with the drawing issues I am encountering?

anda_skoa
31st December 2015, 10:16
It seems though that I am able to work perfectly fine without using a model in conjunction with my views. Is there a compelling reason to use a model other than separatinjg data from the UI elements?

Well, if you want the views to do anything, then they need data to work on.
You either provide the data via a model, i.e. either one of the standard models or a custom model, or you use the item widgets with their built-in models.



BTW, in relation to the original thread I have the QDockWidget containing my QTableView which contains a QTableWidget. Do you think this has anything to do with the drawing issues I am encountering?

QTableView is usually not a container widget, so what do you mean with "it contains a QTableWidget"?

Cheers,
_

Caolan O'Domhnaill
2nd January 2016, 21:33
Well, if you want the views to do anything, then they need data to work on.
You either provide the data via a model, i.e. either one of the standard models or a custom model, or you use the item widgets with their built-in models.
_

For example I have in the subclassed View class my data which is at the bottom of the class definition.



class PhysEqSolver : public QTableView, public PhysCommon {
Q_OBJECT
public:
PhysEqSolver(int rows = 0, int cols = 1, QWidget * = NULL);

void CartesianDataObj(CartesianGraphDataObj *pObj) { m_pTable -> CartesianDataObj(pObj); }
QList<PhysParticle *> Particles() const { return m_pTable -> CartesianDataObj() ->Particles(); }
QList<PhysVector *> Vectors() const { return m_pTable -> CartesianDataObj() ->Vectors(); }

PhysEqSolverTable *Table() const { return m_pTable; }

private:
void createParticleItems(int, PhysParticle *);
void create1DKinematicItems(int, PhysParticle *);
QTableWidgetItem *createRowItem(PhysDataObj *);
QTableWidgetItem *createTableItem(PhysDataObj *, bool = false);

void createConnections();
void createTable(const int, const int);
void setupTableLookAndFeel();
void createGrid();
void setupContextMenu();

QStringList findVariablesInGrid(PhysEqRow *);
QList<double> findValuesOfVariablesInGrid(PhysEqRow *);

void DecodeAddy(const QString, int *, int * = NULL);
QString EncodeAddy(const int, const int = -1);
void createTimeSliceRow(QList<double>);
void addPhysDataObjCell(const int row, const int col, const QString, const double val);

void createPhysDataObjRow(PhysDataObj *);
public slots:
void updateLineEdit(QTableWidgetItem *);
void returnPressed();
void onAddPhysEqSolverRow(QList<PhysParticle *>);
void onCalculate();
void onUpdateParticleName(const QString, const QString);
void onAddTimeSliceCell(int, double);
void onRemoveTimeSliceCell(int);
void onCartesianGraphCreated(CartesianGraphDataObj *pObj) { m_pTable ->CartesianDataObj(pObj); }
void onSetModType(int modType) {}
signals:
private:
PhysEqSolverTable *m_pTable;
QLineEdit *m_pFormulaInput;
QList<PhysEqRow *> m_lstRows;
PhysEqGrid *m_pGrid;
QList<PhysParticle *> m_lstParticles;
PhysCalculateTimer *m_pCalcTimer;
};




QTableView is usually not a container widget, so what do you mean with "it contains a QTableWidget"?

Cheers,
_

In the code above you can see this line:


PhysEqSolverTable *m_pTable;


Which is a derived QTableWidget. My View class contains this widget.

anda_skoa
2nd January 2016, 22:21
That looks weird.

What do you need the table view for?
It looks like your table is the table widget.

Cheers,
_

d_stranz
2nd January 2016, 23:11
This is a really confused design. "PhysEqSolver" is, in effect, the model, since it appears to be the source of data that is displayed in the table. It is completely unnecessary to derive this from QTableView and in fact that might be part of the source of your GUI problems.

The PhysEqSolverTable table widget that is created as part of the PhysEqSolver class should be the instance that is inserted into the dock widget. It should be created by the code that creates the dock widget (a QMainWindow-based class, likely). If for convenience, you want to store a copy of that pointer in the PhysEqSolver class, that's fine, but the Model / View architecture works the other way around - the model pointer is stored on the view, not vice-versa.

Most of the code you have in the PhysEqSolver class for interacting with the table cells should be moved to the PhysEqSolverTable class. This is probably another source of GUI problems since it is likely you are handling signals for one GUI object (the table VIEW) using a different GUI object (the table WIDGET).

Caolan O'Domhnaill
4th January 2016, 18:52
This is a really confused design. "PhysEqSolver" is, in effect, the model, since it appears to be the source of data that is displayed in the table. It is completely unnecessary to derive this from QTableView and in fact that might be part of the source of your GUI problems.

The PhysEqSolverTable table widget that is created as part of the PhysEqSolver class should be the instance that is inserted into the dock widget. It should be created by the code that creates the dock widget (a QMainWindow-based class, likely). If for convenience, you want to store a copy of that pointer in the PhysEqSolver class, that's fine, but the Model / View architecture works the other way around - the model pointer is stored on the view, not vice-versa.

Most of the code you have in the PhysEqSolver class for interacting with the table cells should be moved to the PhysEqSolverTable class. This is probably another source of GUI problems since it is likely you are handling signals for one GUI object (the table VIEW) using a different GUI object (the table WIDGET).

Ahhhhhhh. Okay...

This was the way that the sample I used was designed. Since I am learning and new to QT I have just run with it.

I'll redesign some and see if that helps the UI issue...

Caolan O'Domhnaill
15th March 2016, 20:10
Hey there Anda I finally had a chance to review this and yes after some investigation I realised that perhaps because I was developing the UI myself rather than use the QT Creator I wasn't doing it correctly. So I branched my code and rebuilt the UI using the QT Creator app, thereby doing it the right way, and many issues I was having are no longer there.

In addition i came to realise that my understanding of the View/Model architecture was sorely lacking so I spent some time with that as well. Although much of my application remains the same, the UI base has been refactored greatly and the problems I was encountering in this thread are now gone. That was because I was confused by the documentation between QTableView and QTableWidget when it said that QTableWidget is a helper class...

Anyway, this problem has now been averted.