2017-05-09 2 views
1

Ich habe ein QTableView mit einem verdeckten liegenden KopfQTableView: interaktive Spalt der Größe ohne QHeaderView

table->horizontalHeader()->hide(); 

No header view

Wie Sie sehen können, wird der Text in der mittleren Spalte wegen der Spaltenbreite abgeschnitten wird.

Um den Text anzuzeigen, müsste der Benutzer die Größe der Spalte ändern, aber ohne eine Kopfzeile kann ich dies nicht tun.

Ich würde gerne in der Lage sein, meine Maus über den Rand der Spalte zu bewegen und das normale Größenänderungssymbol erscheinen zu lassen, und dann dem Benutzer erlauben, die Spalte weiter zu ziehen.

Ist das möglich?

+0

Vielleicht Lösung ist eine Schaltfläche hinzufügen alle Spalten mit 'ResizeColumnsToContents' zu ändern. –

Antwort

1

Haben Sie etwas Ereignisfilter und die folgenden zwei Klassen arbeiten mit ...

/* 
* Subclass of QTableView that provides notification when the mouse cursor 
* enters/leaves a column boundary. 
*/ 
class headerless_table_view: public QTableView { 
    using super = QTableView; 
public: 
    explicit headerless_table_view (QWidget *parent = nullptr) 
    : super(parent) 
    , m_boundary_width(10) 
    , m_column_index(-1) 
    { 
     viewport()->setMouseTracking(true); 
     viewport()->installEventFilter(this); 
    } 

    /* 
    * @return The index of the column whose right hand boundary the cursor lies 
    *   on or -1 if not on a boundary. 
    */ 
    int column_index() const 
    { 
     return(m_column_index); 
    } 
protected: 
    virtual bool eventFilter (QObject *obj, QEvent *event) override 
    { 
     if (event->type() == QEvent::MouseMove) { 
     if (auto *e = dynamic_cast<QMouseEvent *>(event)) { 
      auto col_left = columnAt(e->pos().x() - m_boundary_width/2); 
      auto col_right = columnAt(e->pos().x() + m_boundary_width/2); 
      bool was_on_boundary = m_column_index != -1; 
      if (col_left != col_right) { 
      if (m_column_index == -1) { 
       if (col_left != -1) { 
       m_column_index = col_left; 
       } 
      } 
      } else { 
      m_column_index = -1; 
      } 
      bool is_on_boundary = m_column_index != -1; 
      if (is_on_boundary != was_on_boundary) { 
      entered_column_boundary(is_on_boundary); 
      } 
     } 
     } 
     return(super::eventFilter(obj, event)); 
    } 

    /* 
    * Called whenever the cursor enters or leaves a column boundary. if 
    * `entered' is true then the index of the column can be obtained using 
    * `column_index()'. 
    */ 
    virtual void entered_column_boundary (bool entered) 
    { 
    } 
private: 
    int m_boundary_width; 
    int m_column_index; 
}; 

/* 
* Subclass of headerless_table_view that allows resizing of columns. 
*/ 
class resizable_headerless_table_view: public headerless_table_view { 
    using super = headerless_table_view; 
public: 
    explicit resizable_headerless_table_view (QWidget *parent = nullptr) 
    : super(parent) 
    , m_dragging(false) 
    { 
     viewport()->installEventFilter(this); 
    } 
protected: 
    virtual bool eventFilter (QObject *obj, QEvent *event) override 
    { 
     if (auto *e = dynamic_cast<QMouseEvent *>(event)) { 
     if (event->type() == QEvent::MouseButtonPress) { 
      if (column_index() != -1) { 
      m_mouse_pos = e->pos(); 
      m_dragging = true; 
      return(true); 
      } 
     } else if (event->type() == QEvent::MouseButtonRelease) { 
      m_dragging = false; 
     } else if (event->type() == QEvent::MouseMove) { 
      if (m_dragging) { 
      int delta = e->pos().x() - m_mouse_pos.x(); 
      setColumnWidth(column_index(), columnWidth(column_index()) + delta); 
      m_mouse_pos = e->pos(); 
      return(true); 
      } 
     } 
     } 
     return(super::eventFilter(obj, event)); 
    } 

    /* 
    * Override entered_column_boundary to update the cursor sprite when 
    * entering/leaving a column boundary. 
    */ 
    virtual void entered_column_boundary (bool entered) override 
    { 
     if (entered) { 
     m_cursor = viewport()->cursor(); 
     viewport()->setCursor(QCursor(Qt::SplitHCursor)); 
     } else { 
     viewport()->setCursor(m_cursor); 
     } 
    } 
private: 
    bool m_dragging; 
    QPoint m_mouse_pos; 
    QCursor m_cursor; 
}; 

landete ich es in zwei Klassen Aufspaltung wie es sauberer zu sein schien.

Wie auch immer, einfach ersetzen QTableView durch resizable_headerless_table_view in einigen alten Beispielcode gefunden schien den gewünschten Effekt zu haben - das Cursor Sprite ändert sich, wenn die Maus über eine Spaltengrenze und die relevante Grenze gezogen werden kann.

Nicht sicher, wie nah es ist, was Sie nach, aber ...

+0

Wow, das ist großartig, danke! Ich werde es versuchen! –

Verwandte Themen