A
Nov. 3, 2020, 5:23 p.m.

Перемещение столбцов и строк в QTableView средней кнопкой мыши

QTableView

Здравствуйте!
Пишу реализацию таблиц через QTableView. Возникла небольшая проблема с тем, что перемещение столбцов и строк производится той же клавишей мыши, что и выделение. В связи с чем решил перенести реализацию перемещения на среднюю кнопку мыши. Однако не до конца понятно как это сделать.

2

Do you like it? Share on social networks!

4
ДК
  • Nov. 3, 2020, 7:02 p.m.
  1. void TableView::mousePressEvent(QMouseEvent *event)
  2. {
  3. if (event->button() == Qt::MiddleButton)
  4. {
  5. //your logics
  6. }
  7.  
  8. TableView::mousePressEvent(event);
  9. }
    A
    • Nov. 6, 2020, 1:55 p.m.
    • (edited)

    Я понимаю что там нужно делать переопределение mouse...Event, однако в логике я не разобрался

    tableview.h

    1. #ifndef TABLEVIEW_H
    2. #define TABLEVIEW_H
    3.  
    4. #include <QTableView>
    5. #include <QStandardItemModel>
    6.  
    7. #include <QHeaderView>
    8. #include <QMouseEvent>
    9.  
    10. #include "../const.h"
    11.  
    12. class TableView : public QTableView
    13. {
    14. Q_OBJECT
    15. public:
    16. explicit TableView(QStandardItemModel *item_model,QWidget *parent = nullptr);
    17. ~TableView();
    18.  
    19. static int SumTables;
    20. static int ResTableWidgetID;
    21.  
    22. private:
    23. int tableWidgetID = 0;
    24. QHeaderView *horizontalHeaderView;
    25. };
    26.  
    27. class HorizontalHeaderView : public QHeaderView
    28. {
    29. Q_OBJECT
    30. public:
    31. explicit HorizontalHeaderView(QWidget *parent = nullptr);
    32. ~HorizontalHeaderView();
    33.  
    34. protected:
    35. void mousePressEvent(QMouseEvent *event) override;
    36. void mouseMoveEvent(QMouseEvent *event) override;
    37. void mouseReleaseEvent(QMouseEvent *event) override;
    38.  
    39. };
    40.  
    41. #endif // TABLEVIEW_H

    tableview.cpp

    1. #include "tableview.h"
    2.  
    3. #include <QDebug>
    4.  
    5. int TableView::SumTables = 0;
    6. int TableView::ResTableWidgetID = 0;
    7.  
    8. TableView::TableView(QStandardItemModel *item_model, QWidget *parent) :
    9. QTableView(parent)
    10. {
    11. SumTables++;
    12. ResTableWidgetID++;
    13. tableWidgetID = ResTableWidgetID;
    14.  
    15. this->resize(GBS_TABLE_MIN_WIDTH,GBS_TABLE_MIN_HEIGHT);
    16. this->setWindowIcon(QIcon(GBS_TABLE_ICON));
    17. this->setWindowTitle(tr("Table ")+QString::number(tableWidgetID));
    18.  
    19. horizontalHeaderView = new HorizontalHeaderView(this);
    20. this->setHorizontalHeader(horizontalHeaderView);
    21.  
    22. this->setModel(item_model);
    23. }
    24.  
    25. TableView::~TableView()
    26. {
    27. SumTables--;
    28. if (SumTables == 0)
    29. ResTableWidgetID = 0;
    30. }
    31.  
    32. HorizontalHeaderView::HorizontalHeaderView(QWidget *parent) :
    33. QHeaderView(Qt::Horizontal,parent)
    34. {
    35. this->setContextMenuPolicy(Qt::CustomContextMenu);
    36. this->setSectionsMovable(true);
    37. this->setSectionsClickable(true);
    38. this->setSectionResizeMode(QHeaderView::Interactive);
    39. }
    40.  
    41. HorizontalHeaderView::~HorizontalHeaderView()
    42. {
    43.  
    44. }
    45.  
    46. void HorizontalHeaderView::mousePressEvent(QMouseEvent *event)
    47. {
    48. if (event->button() == Qt::MiddleButton)
    49. {
    50. this->sectionPressed(this->logicalIndexAt(event->pos()));
    51. }
    52. QHeaderView::mousePressEvent(event);
    53. }
    54.  
    55. void HorizontalHeaderView::mouseMoveEvent(QMouseEvent *event)
    56. {
    57. if (event->button() == Qt::MidButton)
    58. {
    59.  
    60. }
    61. QHeaderView::mouseMoveEvent(event);
    62. }
    63.  
    64. void HorizontalHeaderView::mouseReleaseEvent(QMouseEvent *event)
    65. {
    66. QHeaderView::mouseReleaseEvent(event);
    67. }
      ДК
      • Nov. 6, 2020, 6:21 p.m.

      ситуация: есть основное окно - QDialog, к примеру. В нем есть таблица, при нажатии ср кн мыши на которую, должна выполняться какая-то логика.
      1) Делаем наследника от QTableView и в этом классе переопределяем только mouseMoveEvent (если нам только это поведение вью нужно изменить).
      2) Если мы работает через форму: пр клик мыши на QTableView->"перобразовать в" и в открывшемся окне преобразовываем вью в наследника.

      3) Всё. Вью готова. Можно залезать обратно в вашу форму, в которой вы устанавливаете модель для этой вью и там работать дальше.
      4) Всё будет ок, если у вас нет делегатов. Если есть делегаты, а ячейки таблицы также имеют определенные виджеты, то тогда нужно будет смотреть по ситуации где правильнее использовать этот эвент.

        A
        • Nov. 7, 2020, 10:53 p.m.
        • (edited)

        Посидев немного над исходниками Qt, понял простоту решения проблемы, жаль, правда, что не так красиво перемещается, как при оригинальном выполнении

        tableview.h

        1. #ifndef TABLEVIEW_H
        2. #define TABLEVIEW_H
        3.  
        4. #include <QTableView>
        5. #include <QStandardItemModel>
        6.  
        7. #include <QHeaderView>
        8. #include <QMouseEvent>
        9. #include <QApplication>
        10.  
        11. #include "../const.h"
        12.  
        13. class TableView : public QTableView
        14. {
        15. Q_OBJECT
        16. public:
        17. explicit TableView(QStandardItemModel *item_model,QWidget *parent = nullptr);
        18. ~TableView();
        19.  
        20. static int SumTables;
        21. static int ResTableWidgetID;
        22.  
        23. private:
        24. int tableWidgetID = 0;
        25. QHeaderView *horizontalHeaderView;
        26. };
        27.  
        28. class HorizontalHeaderView : public QHeaderView
        29. {
        30. Q_OBJECT
        31. public:
        32. explicit HorizontalHeaderView(QWidget *parent = nullptr);
        33. ~HorizontalHeaderView();
        34. private:
        35. bool pressMiddleButton = 0;
        36. int firstPos;
        37. int lastPos;
        38. protected:
        39. void mousePressEvent(QMouseEvent *event) override;
        40. void mouseMoveEvent(QMouseEvent *event) override;
        41. void mouseReleaseEvent(QMouseEvent *event) override;
        42. };
        43.  
        44. #endif // TABLEVIEW_H

        tableview.cpp

        1. #include "tableview.h"
        2.  
        3. #include <QDebug>
        4.  
        5. int TableView::SumTables = 0;
        6. int TableView::ResTableWidgetID = 0;
        7.  
        8. TableView::TableView(QStandardItemModel *item_model, QWidget *parent) :
        9. QTableView(parent)
        10. {
        11. SumTables++;
        12. ResTableWidgetID++;
        13. tableWidgetID = ResTableWidgetID;
        14.  
        15. this->resize(GBS_TABLE_MIN_WIDTH,GBS_TABLE_MIN_HEIGHT);
        16. this->setWindowIcon(QIcon(GBS_TABLE_ICON));
        17. this->setWindowTitle(tr("Table ")+QString::number(tableWidgetID));
        18.  
        19. horizontalHeaderView = new HorizontalHeaderView(this);
        20. this->setHorizontalHeader(horizontalHeaderView);
        21.  
        22. this->setModel(item_model);
        23.  
        24. connect(item_model,&QStandardItemModel::itemChanged,this,&TableView::slotNexCell);
        25. }
        26.  
        27. TableView::~TableView()
        28. {
        29. SumTables--;
        30. if (SumTables == 0)
        31. ResTableWidgetID = 0;
        32. }
        33.  
        34. HorizontalHeaderView::HorizontalHeaderView(QWidget *parent) :
        35. QHeaderView(Qt::Horizontal,parent)
        36. {
        37. this->setContextMenuPolicy(Qt::CustomContextMenu);
        38. this->setSectionsClickable(true);
        39. this->setSectionResizeMode(QHeaderView::Interactive);
        40. }
        41.  
        42. HorizontalHeaderView::~HorizontalHeaderView()
        43. {
        44.  
        45. }
        46.  
        47. void HorizontalHeaderView::mousePressEvent(QMouseEvent *event)
        48. {
        49. if (event->button() == Qt::MiddleButton)
        50. {
        51. pressMiddleButton = 1;
        52. firstPos = event->pos().x();
        53. this->sectionPressed(this->logicalIndexAt(event->pos()));
        54. }
        55. QHeaderView::mousePressEvent(event);
        56. }
        57.  
        58. void HorizontalHeaderView::mouseMoveEvent(QMouseEvent *event)
        59. {
        60. if (pressMiddleButton)
        61. {
        62. int pos = event->pos().x();
        63. if (pos < 0)
        64. return;
        65. int visual = visualIndexAt(pos);
        66. if (visual == -1)
        67. return;
        68. lastPos = pos;
        69. }
        70. QHeaderView::mouseMoveEvent(event);
        71. }
        72.  
        73. void HorizontalHeaderView::mouseReleaseEvent(QMouseEvent *event)
        74. {
        75. if (event->button() == Qt::MiddleButton)
        76. {
        77. int from = visualIndexAt(firstPos);
        78. int to = visualIndexAt(lastPos);
        79. if (from != -1 && to != -1)
        80. this->moveSection(from,to);
        81. pressMiddleButton = 0;
        82. }
        83. QHeaderView::mouseReleaseEvent(event);
        84. }

          Comments

          Only authorized users can post comments.
          Please, Log in or Sign up
          • Last comments
          • AK
            April 1, 2025, 11:41 a.m.
            Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
          • Evgenii Legotckoi
            March 9, 2025, 9:02 p.m.
            К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
          • VP
            March 9, 2025, 4:14 p.m.
            Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
          • ИМ
            Nov. 22, 2024, 9:51 p.m.
            Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
          • Evgenii Legotckoi
            Oct. 31, 2024, 11:37 p.m.
            Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup