qt - QTreeView: column resize from columns and not from headers? -
is there way allow user interactively resize columns when headers hidden?
you can install event filter on table's viewport , implement needed behavior manually. below sample implementation.
header:
#include <qtableview> class table_cell_resizer : public qobject { q_object public: explicit table_cell_resizer(qtableview *view = 0); protected: bool eventfilter(qobject* object, qevent* event); private: qtableview* m_view; //max distance between mouse , cell, small enough trigger resize int m_sensibility; //variables saving state while dragging bool m_drag_in_progress; qt::orientation m_drag_orientation; int m_drag_section; int m_drag_previous_pos; // check if mouse_pos around right or bottom side of cell // (depending on orientation) // , return index of cell if found qmodelindex index_resizable(qpoint mouse_pos, qt::orientation orientation); };
source:
#include "table_cell_resizer.h" #include <qmouseevent> #include <qheaderview> table_cell_resizer::table_cell_resizer(qtableview* view) : qobject(view), m_view(view) { m_view->viewport()->installeventfilter(this); m_view->viewport()->setmousetracking(true); m_sensibility = 5; m_drag_in_progress = false; } bool table_cell_resizer::eventfilter(qobject* object, qevent* event) { if (object == m_view->viewport()) { qmouseevent* mouse_event = dynamic_cast<qmouseevent*>(event); if (mouse_event) { if (mouse_event->type() == qevent::mousemove) { if (m_drag_in_progress) { // apply dragging int delta; qheaderview* header_view; if (m_drag_orientation == qt::vertical) { delta = mouse_event->pos().y() - m_drag_previous_pos; header_view = m_view->verticalheader(); m_drag_previous_pos = mouse_event->pos().y(); } else if (m_drag_orientation == qt::horizontal) { delta = mouse_event->pos().x() - m_drag_previous_pos; header_view = m_view->horizontalheader(); m_drag_previous_pos = mouse_event->pos().x(); } //using minimal size = m_sensibility * 2 prevent collapsing header_view->resizesection(m_drag_section, qmax(m_sensibility * 2, header_view->sectionsize(m_drag_section) + delta)); return true; } else { // set mouse cursor shape if (index_resizable(mouse_event->pos(), qt::vertical).isvalid()) { m_view->viewport()->setcursor(qt::splitvcursor); } else if (index_resizable(mouse_event->pos(), qt::horizontal).isvalid()) { m_view->viewport()->setcursor(qt::splithcursor); } else { m_view->viewport()->setcursor(qcursor()); } } } else if (mouse_event->type() == qevent::mousebuttonpress && mouse_event->button() == qt::leftbutton && !m_drag_in_progress) { // start dragging if (index_resizable(mouse_event->pos(), qt::vertical).isvalid()) { m_drag_in_progress = true; m_drag_orientation = qt::vertical; m_drag_previous_pos = mouse_event->y(); m_drag_section = index_resizable(mouse_event->pos(), qt::vertical).row(); return true; } else if (index_resizable(mouse_event->pos(), qt::horizontal).isvalid()) { m_drag_in_progress = true; m_drag_orientation = qt::horizontal; m_drag_previous_pos = mouse_event->x(); m_drag_section = index_resizable(mouse_event->pos(), qt::horizontal).column(); return true; } } else if (mouse_event->type() == qevent::mousebuttonrelease && mouse_event->button() == qt::leftbutton && m_drag_in_progress) { // stop dragging m_drag_in_progress = false; return true; } } } return false; } qmodelindex table_cell_resizer::index_resizable(qpoint mouse_pos, qt::orientation orientation) { qmodelindex index = m_view->indexat(mouse_pos - qpoint(m_sensibility + 1, m_sensibility + 1)); if (index.isvalid()) { if (orientation == qt::horizontal) { if (qabs(m_view->visualrect(index).right() - mouse_pos.x()) < m_sensibility && m_view->horizontalheader()->sectionresizemode(index.column()) == qheaderview::interactive) { return index; } } else { if (qabs(m_view->visualrect(index).bottom() - mouse_pos.y()) < m_sensibility && m_view->verticalheader()->sectionresizemode(index.row()) == qheaderview::interactive) { return index; } } } return qmodelindex(); }
usage:
new table_cell_resizer(ui->table);
user can resize rows , columns using cell area in addition header areas. can hide headers if wish. implementation respects header resize modes, make sure resize mode set qheaderview::interactive
headers want resizable. example, can set horizontal header mode interactive
, vertical header mode fixed
, resulting in resizable columns , fixed rows.
Comments
Post a Comment