自訂Qt視窗組件實現一個十六進位的SpinBox,一般SpinBox只支援十進位整數,但是可以子類化方法實現該功能需重新實現以下虛函數
virtual QStringtextFromValue ( int value ) constvirtual intvalueFromText ( const QString & text ) const
例如:(摘抄自QtAssitant)
int IconSizeSpinBox::valueFromText(const QString &text) const { QRegExp regExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?")); if (regExp.exactMatch(text)) { return regExp.cap(1).toInt(); } else { return 0; } } QString IconSizeSpinBox::textFromValue(int value) const { return tr("%1 x %1").arg(value); }
自己實現hexspinBox的代碼
#ifndef HEXSPINBOX_H#define HEXSPINBOX_H#include <QSpinBox>class QRegExpValidator;class hexspinBox : public QSpinBox{ Q_OBJECT public: explicit hexspinBox(QWidget *parent = 0); ~hexspinBox(); protected: //重寫基類函數 QValidator::State validate(QString &input, int &pos) const; int valueFromText(const QString &text) const; QString textFromValue(int val) const;private: QRegExpValidator *validator;};#endif // HEXSPINBOX_H
//實現代碼
#include "hexspinbox.h"#include <QSpinBox>hexspinBox::hexspinBox(QWidget *parent) : QSpinBox(parent){ setRange(0, 255); validator = new QRegExpValidator(QRegExp("[0-9A-Fa-F]{0, 8}"), this);}QValidator::State hexspinBox::validate(QString &input, int &pos) const{ return validator->validate(input, pos);}QString hexspinBox::textFromValue(int val) const{ return QString::number(val, 16).toUpper();}int hexspinBox::valueFromText(const QString &text) const{ bool ok; return text.toInt(&ok, 16);}
子類化QWidget
當手裡沒有任何一個Qt視窗組件能夠滿足任何任務需求時,我們可以建立自己想要的視窗組件。要實現這一點,只需通過子類化QWidget,並且通過重新實現一些用來繪製視窗組件和相應滑鼠點擊的事件處理器即可
比如繼承QWidget類例如,建立一個可以改變地區顏色的簡單圖形介面程式先讓主類繼承QWidget,在重寫需要自己實現的虛函數,如下面的 mousePressEvent , mouseMoveEvent, paintEvent
class IconEditor : public QWidget{ Q_OBJECT //聲明類的屬性 Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor) Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage) Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor) public: explicit IconEditor(QWidget *parent = 0); ~IconEditor(); void setPenColor(const QColor &newColor); QColor penColor() const { return curColor; } void setZoomFactor(int newZoom); int zoomFactor() const { return zoom; } void setIconImage(const QImage &newImage); QImage iconImage() const { return image; } QSize sizeHint() const; protected: void mousePressEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); void paintEvent(QPaintEvent *); private: void setImagePixel(const QPoint &pos, bool opaque); QRect pixelRect(int i, int j) const; QColor curColor; QImage image; int zoom;};
再依次實作類別中的函數,與MFC中自繪控制項是一回事。以下是cpp中部分代碼
void IconEditor::paintEvent(QPaintEvent *event){ QPainter painter(this); if(zoom>=3){ painter.setPen(palette().foreground().color()); for(int i=0; i<=image.width(); i++){ painter.drawLine(zoom*i, 0, zoom*i, zoom*image.height()); for(int j=0; j<=image.height(); j++){ painter.drawLine(0, zoom*j, zoom*image.width(), zoom*j); } for(int i=0; i<image.width(); i++){ for(int j=0; j<image.height(); j++){ QRect rect = pixelRect(i, j); if(!event->region().intersected(rect).isEmpty()){ QColor color = QColor::fromRgba(image.pixel(i, j)); if(color.alpha()<255) painter.fillRect(rect, Qt::white); painter.fillRect(rect, color); } } } } }}
void IconEditor::mousePressEvent(QMouseEvent *event){ if(event->button() == Qt::LeftButton){ setImagePixel(event->pos(), true); } else if(event->button()==Qt::RightButton){ setImagePixel(event->pos(), false); }}void IconEditor::mouseMoveEvent(QMouseEvent *event){ if(event->buttons() & Qt::LeftButton){ setImagePixel(event->pos(), true); } else if(event->buttons() & Qt::RightButton){ setImagePixel(event->pos(), false); }}程式運行: