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

在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 将这个事件对象传递给QObjectevent()函数。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() 直接可以被发出。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值