QStyle类&&委托

建一个自定义的样式有两种方法:

一种是静态的创建就是继承已有的类,然后实现虚函数。另外一种就是使用QProxyStyle。

基础类的介绍:

QStyle基类,它派生出了:
QMotifStyle ,QWindowsStyle,QCDEStyle,QCleanlooksStyle ,QPlastiqueStyle,QWindowsXPStyle等等样式,QMacStyle在Windows平台下无法使用,

首先我们从他们派生自己的类:例如:class  myStyle: public QMotifStyle{};

然后重载其中几个重要的要使用的函数。

最后使用:在main函数中return exec()之前添加这么一句:qApp->setStyle(new myStyle);//设置整个应用的样式

也可以通过QWidget::setStyle()函数为单个窗口部件设置样式。

※整个应用的样式可以通过QApplication::setStyle()函数设置。它也可以被用户使用-style命令行参数指定:
   ./myapplication -style myStyle
※如果没有指定样式,Qt会自动为用户平台或者是桌面环境选择最适合的样式。
※我们也可以通过QWidget::setStyle()函数为单个窗口部件设置样式。

//以下三个函数在装载Style和卸载Style时调用,它可以是适当修改窗口部件和调色板
void polish(QPalette &palette);
void polish(QWidget *widget);
void unpolish(QWidget *widget);
 //设置各部件的线宽,大小等
int pixelMetric(PixelMetric metric, const QStyleOption *option,const QWidget *widget) const;
//分别设置各种部件的布局,比如checkbox的text在左边或者在右边
int styleHint(StyleHint hint, const QStyleOption *option,const QWidget *widget, QStyleHintReturn *returnData) const;
 //这个则是最重要的,在这里面你要实现对不同部件的绘制,当然你也可以调用默认的方法.
void drawPrimitive(PrimitiveElement element, const QStyleOption *option,QPainter *painter, const QWidget *widget) const;
 

大部分的QStyle函数使用四个参数:*一个枚举值,用来指定绘制哪一个图形元素;*一个QStyleOption参数,指定如何、在哪里渲染该图形元素;*一个QPainter,用来绘制该图形元素;*一个QWidget,指定将在哪里绘制该图形元素(可选参数)。

 

 

元素视图的样式视图中元素的绘制是通过代理(委托)实现的。Qt默认的代理,QStyleDelegate,也用于计算矩形元素的边框,以及它们的子元素用于不同元素的数据类型QStyleItemDelegate的支持。

委托就是对视图中显示的项的外观进行完全控制,或者允许对可编辑项提供自己的编辑器或者二者兼备。不同于经典的 Model-View-ControllerMVC)模式,model/view没有将用户交互部分完全分离。一般地,视图将数据向用户进行展示并且处理通用的输入。但是,对于某些特殊要求(比如这里的要求必须输入数字),则交予委托完成。这些组件提供输入功能,同时也能渲染某些特殊数据项。委托的接口由 QAbstractItemDelegate定义。在这个类中,委托通过 paint() sizeHint()两个函数渲染用户内容(也就是说,你必须自己将渲染器绘制出来)。为使用方便,从 4.4开始,Qt 提供了另外的基于组件的子类:QItemDelegate QStyledItemDelegate。默认的委托是 QStyledItemDelegate。二者的区别在于绘制和向视图提供编辑器的方式。QStyledItemDelegate使用当前样式绘制,并且能够使用 Qt Style Sheet(我们会在后面的章节对 QSS进行介绍),因此我们推荐在自定义委托时,使用 QStyledItemDelegate作为基类。不过,除非自定义委托需要自己进行绘制,否则,二者的代码其实是一样的。

继承 QStyledItemDelegate需要实现以下几个函数:

    · createEditor():返回一个组件。该组件会被作为用户编辑数据时所使用的编辑器,从模型中接受数据,返回用户修改的数据。(//创建你编辑时候的控件

    · setEditorData():提供上述组件在显示时所需要的默认值。(//编辑的时候设置数据到上面创建的editor中

    · updateEditorGeometry():确保上述组件作为编辑器时能够完整地显示出来。(//设置编辑控件的位置和大小。样式等)

    ·setModelData():返回给模型用户修改过的数据。(//编辑完成,保存数据到data中

To render an item in a custom way, you must implement paint() and sizeHint(). The QItemDelegate class provides default implementations for these functions; if you do not need custom rendering, subclass that class instead.

We give an example of drawing a progress bar in items; in our case for a package management program.

We create the WidgetDelegate class, which inherits from QStyledItemDelegate. We do the drawing in the paint() function:

 

paint()可能用到的绘制函数:

void QStyle::drawItemPixmap(QPainter * painter, const QRect &rectangleint alignment, const QPixmap & pixmap) const[virtual]

void QStyle::drawItemText(QPainter * painter, const QRect &rectangleint alignment, const QPalette & palettebool enabled, const QString & textQPalette::ColorRole textRole = QPalette::NoRole) const [virtual]

void QStyle::drawControl(ControlElement element, constQStyleOption * optionQPainter * painter, const QWidget *widget = 0) const [pure virtual]

void QStyle::drawComplexControl(ComplexControl control, constQStyleOptionComplex * optionQPainter * painter, constQWidget * widget = 0) const [pure virtual]

继承QItemDelegate之后要用到的。

void drawBackground(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
virtual void drawCheck(QPainter * painter, const QStyleOptionViewItem & option, const QRect & rect, Qt::CheckState state) const
virtual void drawDecoration(QPainter * painter, const QStyleOptionViewItem & option, const QRect & rect, const QPixmap & pixmap) const
virtual void drawDisplay(QPainter * painter, const QStyleOptionViewItem & option, const QRect & rect, const QString & text) const
virtual void drawFocus(QPainter * painter, const QStyleOptionViewItem & option, const QRect & rect) const

※※注意最后要是加上委托之后没有出现预想的画面,这有可能是需要再调用一次:

void paint(QPainter*painter,constQStyleOptionViewItem&option,constQModelIndex&index)const

对可编辑项提供自己的编辑器的例子:Qt自带例子

http://qt-project.org/doc/qt-4.8/itemviews-spinboxdelegate.html

不错的关于委托的博客http://qimo601.iteye.com/blog/1539147

 

参考:http://blog.csdn.net/chenlong12580/article/details/7428578

           http://blog.csdn.net/playstudy/article/details/7897577

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,那么首先我们需要创建一个继承自QStyledItemDelegate的自定义委托,用来绘制选中背景颜色。在这个委托中,我们需要重载paint()函数来实现绘制: ```python class MyDelegate(QStyledItemDelegate): def paint(self, painter, option, index): # 绘制背景色 if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()) # 绘制文本 super().paint(painter, option, index) ``` 然后我们创建一个继承自QTableView的自定义表格视图,用来处理鼠标右键操作和标题合并单元格。我们需要在这个中重载mousePressEvent()函数来实现右键全选操作,并且重载setModel()函数来实现标题的合并单元格: ```python class MyTableView(QTableView): def __init__(self, parent=None): super().__init__(parent) self.setSelectionBehavior(QTableView.SelectItems) def mousePressEvent(self, event): if event.button() == Qt.RightButton: self.selectAll() else: super().mousePressEvent(event) def setModel(self, model): super().setModel(model) # 合并标题单元格 self.setSpan(0, 0, 1, 2) self.setSpan(0, 2, 1, 7) ``` 最后,我们需要提供一个函数接口来设置一天的24小时是否选中,这个接口可以在数据模型中实现。我们需要创建一个继承自QAbstractTableModel的自定义数据模型,用来处理数据和选中状态。在这个模型中,我们需要定义一个二维列表来保存每个单元格的选中状态,然后在setData()函数中更新这个列表,并且在data()函数中根据这个列表返回对应的数据和选中状态: ```python class MyModel(QAbstractTableModel): def __init__(self, parent=None): super().__init__(parent) self.dataList = [[0] * 48 for i in range(7)] def rowCount(self, parent=QModelIndex()): return 7 def columnCount(self, parent=QModelIndex()): return 48 def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return QVariant() elif role == Qt.DisplayRole: return str(self.dataList[index.row()][index.column()]) elif role == Qt.BackgroundRole: if self.dataList[index.row()][index.column()] == 1: return QColor(Qt.green) else: return QColor(Qt.white) elif role == Qt.CheckStateRole: if self.dataList[index.row()][index.column()] == 1: return Qt.Checked else: return Qt.Unchecked else: return QVariant() def setData(self, index, value, role=Qt.EditRole): if index.isValid() and role == Qt.CheckStateRole: if value == Qt.Checked: self.dataList[index.row()][index.column()] = 1 else: self.dataList[index.row()][index.column()] = 0 self.dataChanged.emit(index, index, [role]) return True else: return False ``` 现在我们可以将这些组合起来,来实现一个带有选中背景颜色和右键全选操作的表格视图,并且标题合并单元格和数据的选中状态也已经处理好了: ```python class MyWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.table = MyTableView() self.model = MyModel() self.delegate = MyDelegate() self.table.setModel(self.model) self.table.setItemDelegate(self.delegate) layout = QHBoxLayout(self) layout.addWidget(self.table) def setDaySelected(self, row, selected): for i in range(48): index = self.model.index(row, i) self.model.setData(index, Qt.Checked if selected[i] else Qt.Unchecked, Qt.CheckStateRole) ``` 这里我们提供了一个setDaySelected()函数接口,用来设置一天对应24小时48个时间格子是否选中。你可以根据自己的需要来调用这个函数来更新数据模型中对应的选中状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值