Qt-准备战斗

准备战斗

第一次画自定义窗口部件

t8/lcdrange.h包含LCDRange类定义
• t8/lcdrange.cpp包含LCDRange类实现
• t8/cannon.h包含CannonField类定义
• t8/cannon.cpp包含CannonField类实现
• t8/main.cpp包含MyWidget和main

lcdrange.h

#ifndef LCDRANGE_H
#define LCDRANGE_H
#include <QVBoxLayout>
#include <QWidget>

class QSlider;

class LCDRange:public QWidget
{
    Q_OBJECT
public:
    LCDRange(QWidget *parent = 0);
    int showValue() const;//查询滑块的值
public slots:
    void setValue(int);//设置滑块的值
    void setRange(int minVal, int maxVal);//设置滑块的范围
signals:
    void valueChanged(int);
private:
    QSlider *slider;

};

#endif // LCDRANGE_H

lcdrange.cpp

#include "lcdrange.h"

#include <QSlider>
#include <QLCDNumber>

LCDRange::LCDRange(QWidget *parent):QWidget(parent)
{
    QLCDNumber *lcd = new QLCDNumber(2);
    slider = new QSlider(Qt::Horizontal);
    slider->setRange(0,99);
    slider->setValue(0);

    connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
    connect(slider, SIGNAL(valueChanged(int)), SIGNAL(valueChanged(int)));

    setFocusProxy(slider);//设置这个窗口部件的焦点为slider

    QVBoxLayout *part = new QVBoxLayout;
    part->addWidget(lcd);
    part->addWidget(slider);
    setLayout(part);
}

int LCDRange::showValue() const
{
    return slider->value();
}

void LCDRange::setValue(int value)
{
    slider->setValue(value);
}

void LCDRange::setRange(int minVal, int maxVal)
{
    if(minVal<0||maxVal>99||minVal>maxVal)
    {
        qWarning("LCDRange::setRange(%d,%d)\n"
                 "\tRange must be 0..99\n"
                 "\tand minVal must not be greater than maxVal", minVal, maxVal);
        return;
    }
    slider->setRange(minVal, maxVal);
}

cannon.h

#ifndef CANNON_H
#define CANNON_H

#include <QWidget>

class CannonField:public QWidget
{
    Q_OBJECT
public:
    CannonField(QWidget *parent = 0);
    int showAngle() const{return angle;}//显示角度值
public slots:
    void setAngle(int degrees);//接受信号:设置角度值
signals:
    void angleChanged(int);//发送信号:角度值变化
protected:
    void paintEvent(QPaintEvent *);//窗口刷新/重绘
private:
    int angle;//角度值

};

#endif // CANNON_H

cannon.cpp

#include "cannon.h"
#include <QPainter>

CannonField::CannonField(QWidget *parent):QWidget(parent)
{
    angle = 45;
    setAutoFillBackground(true);
    setPalette(QPalette(QColor(250,250,200)));
}

void CannonField::setAngle(int degrees)
{
    if(degrees<5)
        degrees = 5;
    if(degrees>70)
        degrees = 70;//限制输入角度范围
    if(angle == degrees)
        return;//如果角度与初始angle相同,返回
    angle = degrees;//若不同,将 angle设置为输入角度
    repaint();//调用绘画函数
    emit angleChanged(angle);//发送angle变化消息
}

void CannonField::paintEvent(QPaintEvent *)
{
    QString s = "Angle = "+QString::number(angle);//创建文本
    QPainter p(this);//创建操作窗口部件的QPaonter
    p.drawText(200, 200, s);//在(200,200)处绘制文本s
}

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QPushButton>
#include <QFont>
#include <QSlider>
#include <QLCDNumber>
#include <QVBoxLayout>
#include <QGridLayout>

#include "lcdrange.h"
#include "cannon.h"


class MyWidget:public QWidget
{
public:
    MyWidget(QWidget *parent = 0);

};

MyWidget::MyWidget(QWidget *parent):QWidget(parent)
{

    QPushButton *quit = new QPushButton("Quit");
    quit->setFont(QFont("Times",18,QFont::Bold));
    connect(quit,SIGNAL(clicked()),qApp,SLOT(quit()));

    LCDRange *lcdRange = new LCDRange;
    lcdRange->setRange(5,70);

    CannonField *cannonField = new CannonField;
    connect(lcdRange, SIGNAL(valueChanged(int)), cannonField, SLOT(setAngle(int)));
    connect(cannonField, SIGNAL(angleChanged(int)), lcdRange, SLOT(setValue(int)));


    QGridLayout *grid = new QGridLayout;
    grid->addWidget(quit, 0, 0);
    grid->addWidget(lcdRange, 1, 0, Qt::AlignTop);
    grid->addWidget(cannonField, 1, 1);
    grid->setColumnStretch(1,10);

    lcdRange->setValue(60);
    lcdRange->setFocus();//对lcdRange窗口设置键盘焦点

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addLayout(grid);
    setLayout(layout);

}

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

    MyWidget w;
    w.show();

    return a.exec();
}


结果截图:

这里写图片描述

用鼠标改变左边滑块的值,lcd屏和右边的绘图界面文本值都会随之变化。按键盘的上下左右键也可控制左边滑块的值,lcd屏和绘图界面的值也随之变化。


1.设置重新定义窗口的大小。如果你把它变窄或者变矮会发生什么?左边一列的大小永远不变,右边一列随窗口增大而增大。

结果截图

小图:
这里写图片描述

全屏:
这里写图片描述

因为图片大小有限,全屏图被缩小了,但其实拖动窗口时左边一列的大小并没有发生任何变化。


2.去掉 AlignTop,左边的滑块和lcd屏窗口会占据整个左边,截图如下:

这里写图片描述


3.如果你给左面的列一个非零的拉伸因数,当你重新定义窗口大小时会发生什么?设置第0列拉伸因子为1,第1列拉伸因子为2,则在窗口大小改变时,它们的比例不变,永远为1:2。

grid->setColumnStretch(0, 1);
grid->setColumnStretch(1, 2);

结果截图

小图:
这里写图片描述

全屏:
这里写图片描述

由于边框截多截少不太一样,比例有一点偏差,但其实比例是完全没变的。


4.试着在QButton::setText()调用中把“Quit”改为“&Quit”。按钮看起来变成什么样子了?
加一个&没变,加两个&&会变成下图:
这里写图片描述

如果你在程序运行的时候按下Alt+Q会发生什么?(在少量键盘中时Meta+Q。)
退出程序


5.把CannonField的文本放到中间。

p.drawText(rect(), Qt::AlignCenter, s);

结果截图:

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值