PDA

View Full Version : how to synchronize 2 view's (Table & tree) scrolls.



prasad_N
31st March 2016, 10:14
I wanted to synchronize 2 views scrolling. I have TableView & TreeView, where I set Table view as header to the Tree view. now I want to move header (table view) in sync with tree view when I scroll tree view horizontally.

I have written below code,, But when I move tree view horizontally table view (header) is not moving same amount as tree moved Instead it is jumping to half of the table.
Below is the code, Please let me know If I am missing something here.


Main:


#include "treemodel.h"
#include "treeview.h"

#include <QApplication>
#include <QFile>
#include <QTreeView>

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

QFile file(":/default.txt");
file.open(QIODevice::ReadOnly);
TreeModel model(file.readAll());
file.close();

treeView view1;
view1.setModel(&model);
view1.show();
view1.setHeaderSettings();

return app.exec();
}



view:


#ifndef TREEVIEW_H
#define TREEVIEW_H

#include <QTableView>
#include <QTreeView>
#include <QDebug>
#include <QHeaderView>
#include <QScrollBar>
#include "treeitem.h"


class treeView : public QTreeView
{
Q_OBJECT
public:
treeView(QWidget *parent = 0);
~treeView();

void setHeaderSettings();


protected:
void resizeEvent(QResizeEvent *event) {
setViewportMargins(0,60, 0, 0);
m_header->setGeometry(0, 0, viewport()->width(), m_header->sizeHint().height());
}
void showEvent(QShowEvent *) {
setViewportMargins(0, m_header->sizeHint().height(), 0, 0);
m_header->setGeometry(0, 0, viewport()->width(), m_header->sizeHint().height());
}

protected slots:
void headerSectionResized(int,int,int);
void SliderMoved(const int& val);
void rangeChanged(int,int);

private:
//CustomHeader *m_header;
QTableView *m_header;
};

#endif // TREEVIEW_H




#include "treeview.h"


treeView::treeView(QWidget *parent) : QTreeView(parent)
{
header()->hide();
m_header = new QTableView(this);
m_header->setFixedHeight(60);
setGeometry(50, 50, 400, 400);

connect(m_header->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(headerSectionResized(int,int,int)));
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(SliderMoved(int)));

connect(m_header->horizontalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(rangeChanged(int,int)));

}

treeView::~treeView()
{

}

void treeView::setHeaderSettings()
{
m_header->setModel(this->model());
rangeChanged(horizontalScrollBar()->minimum(), horizontalScrollBar()->maximum());
}

void treeView::headerSectionResized(int logIndex, int oldSize, int newSize)
{
setColumnWidth(logIndex, newSize);
}

void treeView::SliderMoved(const int &val)
{
//qDebug() << "pos = " << horizontalScrollBar()->sliderPosition() << " val = " << val;
m_header->horizontalScrollBar()->setValue(val);


QScrollBar* s1 = m_header->horizontalScrollBar();
QScrollBar* s2 = horizontalScrollBar();

qDebug() << "Header scroll bar: min= " << s1->minimum() << " max = " << s1->maximum() << " val = " << s1->value();
qDebug() << "view scroll bar: min= " << s2->minimum() << " max = " << s2->maximum() << " val = " << s2->value();
}

void treeView::rangeChanged(int min, int max)
{
//Eevn If I don't do this also, I could see same behavior
QScrollBar* s2 = horizontalScrollBar();
m_header->horizontalScrollBar()->setRange(s2->minimum(), s2->maximum());

qDebug() << "min = " << min << " max = " << max;
}




Model I have taken from simple tree model & please let me know in case you need more information.


Thanks in Advance.

anda_skoa
31st March 2016, 11:21
Do the two scrollbars have the same range?

If not, you might need to calculate the relative position and apply this to the other's range.

Cheers,
_

prasad_N
31st March 2016, 12:54
Do the two scrollbars have the same range?_

No, they are different. that is the reason I am just trying to adjust the header range to actual views range in below way, Now this range is getting changed but the behavior is same.


connect(m_header->horizontalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(rangeChanged(int,int)));
void treeView::rangeChanged(int min, int max)
{
//Eevn If I don't do this also, I could see same behavior
QScrollBar* s2 = horizontalScrollBar();
m_header->horizontalScrollBar()->setRange(s2->minimum(), s2->maximum());

qDebug() << "min = " << min << " max = " << max;
}



If not, you might need to calculate the relative position and apply this to the other's range._
could you elaborate this little more.

anda_skoa
31st March 2016, 13:55
could you elaborate this little more.

Let say one range is 0-100 and the other is 0-200, then a value of 20 in range 1 would be 40 in range 2

Something like


int range1 = r1Max - r1Min;
int value1 = value - r1Min;
double relValue = value1/double(range1);

int range2 = r2Max - r2Min;
int value2 = range2 * relValue;
value = value2 + r2Min;


Cheers,
_

prasad_N
31st March 2016, 18:34
This is some how change the behavior But not exactly the way I wanted. Because of the (int/double) header is moving step by step instead in-sync with actual view.
Actual view is moving smoothly but header is moving step by step, this looks so odd to user, Even If I change both the header ranges to 0 to 100 I could see same behavior.

I am attaching more code here, Please have a look. 11843
Qt5.4.0 & Compiled on Windows7.

prasad_N
3rd April 2016, 07:34
Any help..?? Still struggling with this issue..!

prasad_N
7th April 2016, 10:07
Using Table view/Table widget with QTreeview and trying to sync is not working as expected, But after bit experiments using two tree views is working as expect (being both the ranges are same its working as expected. so suggesting to use same view in case you need sync).