Добавление горизонтального слайдера в QTableWidget

Я пытаюсь создать что-то вроде графика времени для моего видеоплеера. Я решил использовать QTableWidget как график, так как это соответствует моей цели. Мой виджет выглядит так:

введите описание изображения здесь

Я хочу, чтобы зеленая линия проходила через виджет, когда я нажимал на игру. Вот мой пример MVCE:

//View.cpp

View::View(QWidget* parent) :  QGraphicsView(parent)
{
QGraphicsScene* scene = new QGraphicsScene(this);

TableWidget* wgt = new TableWidget;

scene->addWidget(wgt);

QGraphicsLineItem* item = new QGraphicsLineItem(30, 12, 30, wgt->height() - 9);
item->setPen(QPen(QBrush(Qt::green), 3));
item->setFlags(QGraphicsItem::ItemIsMovable);
scene->addItem(item);

setScene(scene);
}

Вот TableWidget

TableWidget::TableWidget(QWidget* parent) : QTableWidget(parent)
{
setColumnCount(10);
setRowCount(10);

//Hides the numbers on the left side of the table
verticalHeader()->hide();

//Prevents top header from highlighting on selection
horizontalHeader()->setHighlightSections(false);

//Makes the cells un-editable
setEditTriggers(QAbstractItemView::NoEditTriggers);

setSelectionMode(QAbstractItemView::MultiSelection);
}

Проблема:

Перемещение элемента строки отражает изменения в сцене, к которой он был добавлен, т.е. когда я перетаскиваю линию с помощью мыши, линия перемещается в сцене, но не внутри TableWidget,

Чего я хочу

Я хочу, чтобы зеленая полоса действовала как горизонтальный слайдер. Это должно пройти через TableWidget по горизонтали заставляя виджет прокручиваться вместе с ним, показывая текущую позицию фрейма, обозначенную цифрами в заголовке.

Примерно так, как показано ниже (обратите внимание на красную линию):

Красная линия

Я знаю, что это может быть не лучшим способом реализации графика времени, но я был бы признателен за любые другие идеи для реализации.

1

Решение

Возможное решение — переписать метод itemChange, чтобы ограничить перемещение, как показано ниже:

#include <QApplication>
#include <QGraphicsRectItem>
#include <QGraphicsView>
#include <QTableWidget>
#include <QHeaderView>
#include <QGraphicsProxyWidget>

class SeekBarItem: public QGraphicsRectItem{
public:
SeekBarItem(QRectF rect, QGraphicsItem *parent=nullptr)
: QGraphicsRectItem(rect, parent)
{
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
setBrush(Qt::red);
}
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value){
if(change == QGraphicsItem::ItemPositionChange){
QPointF p = value.toPointF();

qreal max = parentItem()->boundingRect().bottom()- boundingRect().bottom();
qreal min = parentItem()->boundingRect().top()-boundingRect().top();

if(p.y() > max) p.setY(max);
else if (p.y() < min) p.setY(min);
p.setX(pos().x());
return p;
}
return QGraphicsRectItem::itemChange(change, value);
}
};

class TableWidget: public QTableWidget
{
public:
TableWidget(QWidget* parent=nullptr) : QTableWidget(10, 10, parent)
{
verticalHeader()->hide();
horizontalHeader()->setHighlightSections(false);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setSelectionMode(QAbstractItemView::MultiSelection);
}
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsView view;

QGraphicsScene *scene = new QGraphicsScene;
view.setScene(scene);

QGraphicsProxyWidget *proxy = scene->addWidget(new TableWidget);

QGraphicsRectItem *it = new QGraphicsRectItem(QRectF(0, 0, 10, proxy->boundingRect().height()), proxy);
it->setBrush(Qt::green);

SeekBarItem *seekBarItem = new SeekBarItem(QRectF(-5, 0, 20, 50));
seekBarItem->setParentItem(it);

view.resize(640, 480);
view.show();

return a.exec();
}

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь


Обновить:

#include <QApplication>
#include <QGraphicsRectItem>
#include <QGraphicsView>
#include <QTableWidget>
#include <QHeaderView>
#include <QGraphicsProxyWidget>
#include <QScrollBar>

class TableWidget: public QTableWidget
{
public:
TableWidget(QWidget* parent=nullptr) : QTableWidget(10, 10, parent)
{
verticalHeader()->hide();
horizontalHeader()->setHighlightSections(false);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setSelectionMode(QAbstractItemView::MultiSelection);
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
}
};

class SeekBarItem: public QGraphicsRectItem{
public:
SeekBarItem(int width, QAbstractItemView *view, QGraphicsScene *scene)
: QGraphicsRectItem(nullptr),
proxy(new QGraphicsProxyWidget()),
m_view(view)
{
proxy->setWidget(m_view);
scene->addItem(proxy);
setParentItem(proxy);
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
setBrush(Qt::red);
setRect(0, 0, width, m_view->height());
scrollbar = m_view->horizontalScrollBar();
}
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value){
if(change == QGraphicsItem::ItemPositionChange){
QPointF p = value.toPointF();

qreal max = parentItem()->boundingRect().right()- boundingRect().right();
qreal min = parentItem()->boundingRect().left()-boundingRect().left();

if(p.x() > max) p.setX(max);
else if (p.x() < min) p.setX(min);
p.setY(pos().y());

float percentage = (p.x()-min)*1.0/(max-min);
int value = scrollbar->minimum() + percentage*(scrollbar->maximum() - scrollbar->minimum());
scrollbar->setValue(value);
return p;
}
return QGraphicsRectItem::itemChange(change, value);
}
private:
QGraphicsProxyWidget *proxy;
QAbstractItemView *m_view;
QScrollBar *scrollbar;
};int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsView view;

QGraphicsScene *scene = new QGraphicsScene;
view.setScene(scene);

TableWidget *table =  new TableWidget;

SeekBarItem *seekBarItem = new SeekBarItem(15, table, scene);
view.resize(640, 480);
view.show();

return a.exec();
}

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]