Skip to content

Instantly share code, notes, and snippets.

@csuft
Created January 31, 2018 07:14
Show Gist options
  • Save csuft/f1ae9bba552c6757d8163cc4829fabd9 to your computer and use it in GitHub Desktop.
Save csuft/f1ae9bba552c6757d8163cc4829fabd9 to your computer and use it in GitHub Desktop.
Use custom controls in QTableView
#include "customitemmodel.h"
CustomItemModel::CustomItemModel(const QVector<int>& colsAlignLeft, QObject* parent)
: CustomItemModel(colsAlignLeft, QVector<int>(), QVector<int>(), parent){
}
CustomItemModel::CustomItemModel(const QVector<int>& colsAlignLeft,
const QVector<int>& colsAlignCenter, QObject* parent)
: CustomItemModel(colsAlignLeft, colsAlignCenter, QVector<int>(), parent){
}
CustomItemModel::CustomItemModel(const QVector<int>& colsAlignLeft, const QVector<int>& colsAlignCenter,
const QVector<int>& colsAlignRight, QObject* parent):
QStandardItemModel(parent),
mColsAlignLeft(colsAlignCenter),
mColsAlignCenter(colsAlignCenter),
mColsAlignRight(colsAlignRight){
}
/*
* Since the text alignment defaults to Qt::AlignLeft, we only need to reimplement the other
* two alignments.
*/
QVariant CustomItemModel::data(const QModelIndex& index, int role) const {
if (role == Qt::TextAlignmentRole) {
if (mColsAlignCenter.contains(index.column())) {
return Qt::AlignCenter;
}
if (mColsAlignRight.contains(index.column())) {
return Qt::AlignRight;
}
if (mColsAlignLeft.contains(index.column())) {
return Qt::AlignLeft;
}
}
return QStandardItemModel::data(index, role);
}
class CustomItemModel : public QStandardItemModel
{
Q_OBJECT
public:
explicit CustomItemModel(QObject *parent = Q_NULLPTR){}
CustomItemModel(const QVector<int>& colsAlignLeft, QObject* parent = Q_NULLPTR);
CustomItemModel(const QVector<int>& colsAlignLeft, const QVector<int>& colsAlignCenter, QObject* parent = Q_NULLPTR);
CustomItemModel(const QVector<int>& colsAlignLeft, const QVector<int>& colsAlignCenter, const QVector<int>& colsAlignRight, QObject* parent = Q_NULLPTR);
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
~CustomItemModel(){}
private:
QVector<int> mColsAlignRight;
QVector<int> mColsAlignCenter;
QVector<int> mColsAlignLeft;
};
#include "tableviewdelegate.h"
#include "customitemmodel.h"
QtGuiApplication1::QtGuiApplication1(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setStyleSheet("background: rgb(36,37,38);");
CustomItemModel* itemModel = new CustomItemModel(QVector<int>{0, 1}, this);
itemModel->setColumnCount(3);
ui.tableView->setModel(itemModel);
ui.tableView->horizontalHeader()->setHidden(true);
ui.tableView->horizontalHeader()->setStretchLastSection(true);
ui.tableView->verticalHeader()->setHidden(true);
ui.tableView->setSortingEnabled(true);
ui.tableView->setWordWrap(false);
ui.tableView->setMouseTracking(true);
ui.tableView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui.tableView->setShowGrid(false);
ui.tableView->setItemDelegate(new TableViewDelegate);
ui.tableView->setFrameShape(QFrame::NoFrame);
ui.tableView->setAlternatingRowColors(false);
ui.tableView->setColumnWidth(0, 20);
ui.tableView->setColumnWidth(1, 160);
ui.tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
for (int i = 0; i < 10; i++) {
itemModel->insertRow(i);
itemModel->setData(itemModel->index(i, 0), QString::number(i));
itemModel->setData(itemModel->index(i, 0), QString::number(i), Qt::ToolTipRole);
itemModel->setData(itemModel->index(i, 1), "zhangzhongke");
itemModel->setData(itemModel->index(i, 1), "HUST", Qt::ToolTipRole);
}
}
#include "tableviewdelegate.h"
#include <QApplication>
#include <QMouseEvent>
#include <QToolTip>
TableViewDelegate::TableViewDelegate(QWidget *parent)
: QStyledItemDelegate(parent),
m_pOpenButton(new QPushButton()),
m_pDeleteButton(new QPushButton()),
m_nSpacing(5),
m_nWidth(25),
m_nHeight(20)
{
m_pOpenButton->setStyleSheet("QPushButton {border: none; background-color: transparent; image:url(:/QtGuiApplication1/open);} \
QPushButton:hover {image:url(:/QtGuiApplication1/openHover);} \
QPushButton:pressed {image:url(:/QtGuiApplication1/openPress);}");
m_pDeleteButton->setStyleSheet("QPushButton {border: none; background-color: transparent; image:url(:/QtGuiApplication1/delete);} \
QPushButton:hover {image:url(:/QtGuiApplication1/deleteHover);} \
QPushButton:pressed {image:url(:/QtGuiApplication1/deletePress);}");
m_list << QStringLiteral("Open") << QStringLiteral("Delete");
}
TableViewDelegate::~TableViewDelegate()
{
}
void TableViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
initStyleOption(&viewOption, index);
if (option.state.testFlag(QStyle::State_HasFocus))
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
QStyledItemDelegate::paint(painter, viewOption, index);
if (index.column() == FILE_OPERATE_COLUMN)
{
int nCount = m_list.count();
int nHalf = (option.rect.width() - m_nWidth * nCount - m_nSpacing * (nCount - 1)) / 2;
int nTop = (option.rect.height() - m_nHeight) / 2;
for (int i = 0; i < nCount; ++i)
{
QStyleOptionButton button;
button.rect = QRect(option.rect.left() + nHalf + m_nWidth * i + m_nSpacing * i,
option.rect.top() + nTop, m_nWidth, m_nHeight);
button.state |= QStyle::State_Enabled;
if (button.rect.contains(m_mousePoint))
{
if (m_nType == 0)
{
button.state |= QStyle::State_MouseOver;
}
else if (m_nType == 1)
{
button.state |= QStyle::State_Sunken;
}
}
QWidget *pWidget = (i == 0) ? m_pOpenButton.data() : m_pDeleteButton.data();
QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, pWidget);
}
}
}
bool TableViewDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
if (index.column() != FILE_OPERATE_COLUMN)
return false;
m_nType = -1;
bool bRepaint = false;
QMouseEvent *pEvent = static_cast<QMouseEvent *> (event);
m_mousePoint = pEvent->pos();
int nCount = m_list.count();
int nHalf = (option.rect.width() - m_nWidth * nCount - m_nSpacing * (nCount - 1)) / 2;
int nTop = (option.rect.height() - m_nHeight) / 2;
QApplication::restoreOverrideCursor();
for (int i = 0; i < nCount; ++i)
{
QStyleOptionButton button;
button.rect = QRect(option.rect.left() + nHalf + m_nWidth * i + m_nSpacing * i,
option.rect.top() + nTop, m_nWidth, m_nHeight);
if (!button.rect.contains(m_mousePoint))
continue;
bRepaint = true;
switch (event->type())
{
case QEvent::MouseMove:
{
QApplication::setOverrideCursor(Qt::PointingHandCursor);
m_nType = 0;
QToolTip::showText(pEvent->globalPos(), m_list.at(i));
break;
}
case QEvent::MouseButtonPress:
{
m_nType = 1;
break;
}
case QEvent::MouseButtonRelease:
{
if (i == 0)
{
emit open(index);
}
else
{
emit deleteData(index);
}
break;
}
default:
break;
}
}
return bRepaint;
}
#define FILE_OPERATE_COLUMN 2
class TableViewDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit TableViewDelegate(QWidget *parent = 0);
~TableViewDelegate();
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
signals:
void open(const QModelIndex &index);
void deleteData(const QModelIndex &index);
private:
QPoint m_mousePoint;
QScopedPointer<QPushButton> m_pOpenButton;
QScopedPointer<QPushButton> m_pDeleteButton;
QStringList m_list;
int m_nSpacing;
int m_nWidth;
int m_nHeight;
int m_nType;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment