本篇将总结Qt的窗体——QWidget、QMainWindow和QDialog。很多人对这三个类傻傻分不清楚,其实简单来讲QWidget是所有窗体的基类,而QMainWindow和QDialog都是QWidget的子类,QMainWindow是一种具有标题栏,菜单栏,工具栏和状态栏的窗体,QDialog是我们通常说的对话框。
widget是最基本的用户界面接口,它可以响应鼠标、键盘和其他系统事件,在屏幕上绘制出的窗体。每个widget都是矩形形状的,并且在垂直于屏幕的方向排序。嵌入到父窗体中的widget被称为window。通常来说,windows具有框架和标题栏,比如QMainWindow和QDialog都是windows。
每个widget的构造函数都接受两个参数,分别是:
QWidget拥有很多的成员函数,但是很多都是虚函数,这些功能的实现都将有大量的子类的函数实现,如QLabel, QPushButton, QListWidget, and QTabWidget等等。
没有父窗体的widget通常是一个独立的window(top-level widget)。对于这些widgets,setWindowTitle()和 setWindowIcon()函数可以设置它的标题和图标。
非window的widgets被称作子窗体,他们在父窗体中显示。大部分的Qt widgets都被用作子窗体,比如,在window上显示一个按钮。下图中有一个QGroupBox widget被用于囊括所有的其他widgets并通过QGridLayout提供一种布局,QLabel 和各种Edits都是子窗体。
由于QWidget是QPaintDevice的子类,所以可以在QWidget中应用QPainter得句柄以绘制或重绘窗体。这些绘制操作可以在paintEvent() 函数中实现. 这里我们可以借助一个钟表的Qt工程来体会这个用法。
class AnalogClock : public QWidget
{
Q_OBJECT
public:
AnalogClock(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *event) override;
};
AnalogClock::AnalogClock(QWidget *parent)
: QWidget(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
setWindowTitle(tr("Analog Clock"));
resize(200, 200);
}
void AnalogClock::paintEvent(QPaintEvent *)
{
static const QPoint hourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -40)
};
static const QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -70)
};
QColor hourColor(127, 0, 127);
QColor minuteColor(0, 127, 127, 191);
int side = qMin(width(), height());
QTime time = QTime::currentTime();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);
painter.scale(side / 200.0, side / 200.0);
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
painter.setPen(hourColor);
for (int i = 0; i < 12; ++i) {
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
painter.setPen(Qt::NoPen);
painter.setBrush(minuteColor);
painter.save();
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
painter.setPen(minuteColor);
for (int j = 0; j < 60; ++j) {
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
}
当新建了一个新的窗体后,通常需要重新调用sizeHint() 函数来实现一个合理的默认窗体尺寸大小,通过调用setSizePolicy()来设置一些尺寸变化的策略。window的大小默认是2/3 的桌面大小. 可以调用resize函数来改变它.
事件
Widgets响应用户的操作。Qt通过调用QEvent事件处理函数来传递事件。如果你的widget只有子窗体,你可能不用实现任何事件句柄。如果你想检测鼠标点击事件,只需要在子窗体mousePressEvent()里调用underMouse()函数。下面列出了widget的一些常用事件。
paintEvent() 窗体重绘就会被触发。主要需要自绘内容就必须实现这个函数。
resizeEvent() 窗体大小发生变化被触发。
mousePressEvent() 鼠标在窗体内单击则被触发。
mouseReleaseEvent() 鼠标松开时被触发。这通常用在窗体拖拽。
mouseDoubleClickEvent()鼠标在窗体内双击则被触发。
keyPressEvent() 键盘按键按下则触发。
focusInEvent() 键盘关注则触发。
focusOutEvent() 键盘关注消失则触发。
mouseMoveEvent()鼠标按下且移动则触发,常用语窗体拖拽。
keyReleaseEvent() 键盘按键放开则触发。
wheelEvent() 鼠标滚轮触发。
enterEvent() 鼠标进入窗体区域触发。
leaveEvent()鼠标离开窗体区域触发。
moveEvent() 子窗体相对父窗体移动则触发。
closeEvent() 窗体关闭则触发,如调用了close函数。
下面通过一个例子Scribble Example进一步学习,请移步我的下载频道:
成员函数与属性
Widget的成员函数和属性如下表所示,这些都是作为基类的函数,所以由QWidget派生出的子类们都可以调用以下函数。
Context |
Functions and Properties |
Window functions |
show(), hide(), raise(), lower(), close(). |
Top-level windows |
windowModified, windowTitle, windowIcon, isActiveWindow, activateWindow(), minimized, showMinimized(), maximized, showMaximized(), fullScreen, showFullScreen(), showNormal(). |
Window contents |
update(), repaint(), scroll(). |
Geometry |
pos, x(), y(), rect, size, width(), height(), move(), resize(), sizePolicy, sizeHint(), minimumSizeHint(), updateGeometry(), layout(), frameGeometry, geometry, childrenRect, childrenRegion, adjustSize(), mapFromGlobal(), mapToGlobal(), mapFromParent(), mapToParent(), maximumSize, minimumSize, sizeIncrement, baseSize, setFixedSize() |
Mode |
visible, isVisibleTo(), enabled, isEnabledTo(), modal, isWindow(), mouseTracking, updatesEnabled, visibleRegion(). |
Look and feel |
style(), setStyle(), styleSheet, cursor, font, palette, backgroundRole(), setBackgroundRole(), fontInfo(), fontMetrics(). |
Keyboard focus functions |
focus, focusPolicy, setFocus(), clearFocus(), setTabOrder(), setFocusProxy(), focusNextChild(), focusPreviousChild(). |
Mouse and keyboard grabbing |
grabMouse(), releaseMouse(), grabKeyboard(), releaseKeyboard(), mouseGrabber(), keyboardGrabber(). |
Event handlers |
event(), mousePressEvent(), mouseReleaseEvent(), mouseDoubleClickEvent(), mouseMoveEvent(), keyPressEvent(), keyReleaseEvent(), focusInEvent(), focusOutEvent(), wheelEvent(), enterEvent(), leaveEvent(), paintEvent(), moveEvent(), resizeEvent(), closeEvent(), dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(), dropEvent(), childEvent(), showEvent(), hideEvent(), customEvent(). changeEvent(), |
System functions |
parentWidget(), window(), setParent(), winId(), find(), metric(). |
Context menu |
contextMenuPolicy, contextMenuEvent(), customContextMenuRequested(), actions() |
Interactive help |
setToolTip(), setWhatsThis() |