您的位置:首页 > 编程语言 > Qt开发

Qt 学习笔记3 摘自《Qt 学习之路 2》

2016-05-07 17:08 417 查看
在Qt中,常用的表格类是QTableWidget。

QTableWidget *table = new QTableWidget(4,2);  //新建一4行2列的表格

//设置表格行标题
QStringList headerLabels;
headerLabels << "C1" << "C2";
table->setHorizontalHeaderLabels(headerLabels);

//设置表格行标题的对齐方式
table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);

//设置行表题
QStringList rowLabels;
rowLabels << "Line1" << "Line2" << "Line3" << "Line4";
table->setVerticalHeaderLabels(rowLabels);

//设置每一行的高度
for(int i = 0; i < 4; i++)
table->setRowHeight(i, 22);

//自动调整最后一列的宽度使它和表格的右边界对齐
table->horizontalHeader()->setStretchLastSection(true);

//设置表格的选择方式
table->setSelectionBehavior(QAbstractItemView::SelectItems);

//设置编辑方式
table->setEditTriggers(QAbstractItemView::DoubleClicked);

//设置表格的内容
for (int row = 0; row < 4; ++row)
{
QTableWidgetItem *item0, *item1;
item0 = new QTableWidgetItem;
item1 = new QTableWidgetItem;

QString txt = QString("%1").arg(row + 1);
item0->setText(txt);
table->setItem(row, 0, item0);

txt = QString("%1").arg((row + 1) * 2);
item1->setText(txt);
table->setItem(row, 1, item1);

}

//增加一行
table->setRowCount(5);
QTableWidgetItem *vHeader5 = new QTableWidgetItem("Line5");
table->setVerticalHeaderItem(4, vHeader5);

QTableWidgetItem *item5_0, *item5_1;
item5_0 = new QTableWidgetItem;
item5_1 = new QTableWidgetItem;
item5_0->setText(QString("%1").arg(5));
item5_1->setText(QString("%1").arg(5 * 2));
table->setItem(4, 0, item5_0);
table->setItem(4, 1, item5_1);

事件(event)是由系统或者 Qt 本身在不同的时刻发出的。事件也就是我们通常说的“事件驱动(event
drive)”程序设计的基础概念。

“事件驱动”,我们的程序的执行顺序不再是线性的,而是由一个个事件驱动着程序继续执行。没有事件,程序将阻塞在那里,不执行任何代码。


Qt 中,事件的概念似乎同信号槽类似。一般来说,使用 Qt 组件时,我们关心的更多的是事件关联的一个信号。比如,对于
QPushButton
的鼠标点击,我们不需要关心这个鼠标点击事件,而是关心它的
clicked()
信号的发出。

信号由具体的对象发出,然后会马上交给由
connect()
函数连接的槽进行处理;而对于事件,Qt
使用一个事件队列对所有发出的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部。前一个事件完成后,取出后面的事件进行处理。但是,必要的时候,Qt 的事件也可以不进入事件队列,而是直接处理。信号一旦发出,对应的槽函数一定会被执行。但是,事件则可以使用“事件过滤器”进行过滤,对于有些事件进行额外的处理,另外的事件则不关心。

总的来说,如果我们使用组件,我们关心的是信号槽;如果我们自定义组件,我们关心的是事件。

Qt 程序需要在
main()
函数创建一个
QCoreApplication
对象,然后调用它的
exec()
函数。这个函数就是开始
Qt 的事件循环。在执行
exec()
函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt
将创建一个事件对象。Qt 中所有事件类都继承于
QEvent
。在事件对象创建完毕后,Qt
将这个事件对象传递给
QObject
event()
函数。
event()
函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event
handler)。

在所有组件的父类
QWidget
中,定义了很多事件处理的回调函数,如
keyPressEvent()
keyReleaseEvent()
mouseDoubleClickEvent()
mouseMoveEvent()
mousePressEvent()
mouseReleaseEvent()
等。这些函数都是
protected virtual 的,也就是说,我们可以在子类中重新实现这些函数。
class EventLabel : public QLabel
{
protected:
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
};

void EventLabel::mouseMoveEvent(QMouseEvent *event)
{
this->setText(QString("<center><h1>Move: (%1, %2)</h1></center>")
.arg(QString::number(event->x()), QString::number(event->y())));
}

void EventLabel::mousePressEvent(QMouseEvent *event)
{
this->setText(QString("<center><h1>Press: (%1, %2)</h1></center>")
.arg(QString::number(event->x()), QString::number(event->y())));
}

void EventLabel::mouseReleaseEvent(QMouseEvent *event)
{
QString msg;
msg.sprintf("<center><h1>Release: (%d, %d)</h1></center>",
event->x(), event->y());
this->setText(msg);
}

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

EventLabel *label = new EventLabel;
label->setWindowTitle("MouseEvent Demo");
label->resize(300, 200);
label->show();

return a.exec();
}

为什么要点击鼠标之后才能在
mouseMoveEvent()
函数中显示鼠标坐标值?这是因为
QWidget
中有一个
mouseTracking
属性,该属性用于设置是否追踪鼠标。只有鼠标被追踪时,
mouseMoveEvent()
才会发出。如果
mouseTracking

false(默认即是),组件在至少一次鼠标点击之后,才能够被追踪,也就是能够发出
mouseMoveEvent()
事件。如果
mouseTracking

true,则
mouseMoveEvent()
直接可以被发出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: