最近学会了使用Qt和树莓派,决定制作项目练练手。主要是为了真正掌握Qt开发上位机软件,于是简单做了该项目。主要讲讲自己的思路,供别人参考。

下载地址:Misriter/Qt-SmartHome (github.com)

制作软件和硬件:

1.树莓派4B

2.STM32F103

3.DHT11

4.Qt creator 6.4.3

整体展示:

 

 

 

准备工作:

        首先把需要的库加进来,本项目需要network、qmqtt、serialport、sql、charts,使用的qmqtt库是第三方库。

        然后创建一个QMainWindow取名SmartHome用来搭载页面,这里我搭载了1个滑动页,滑动又搭载了3个页面,分别为首页、连接页、数据页。


    slide = new MySlide(this);
    slide->resize(this->size());

    homepage = new HomePage(this);
    slide->addPage(homepage);

    connectpage = new Connect(this);
    slide->addPage(connectpage);

    chart = new Chart(this);
    slide->addPage(chart);

 

滑动页:

        由于我有一块官方触屏,所以可以开发一下触屏功能,这里简单讲讲滑动怎么实现。笼统地讲就是把几个页面横向塞进一个Widget里面,滑动页不够宽一次只能显示一个页面,如果横向滚动就能显示其它页面。看起来是换页面,其实它们都在同一页,只是隐藏了滚动条改成下方的点(页面指示器),模拟了类似轮播图的效果。

        先创建一个Widget,设置透明、隐藏滚动条。创建一个底部横向布局用来存放页面指示器,设置居中、透明。这里为了方便开发,触屏和鼠标左键都能触发滑动,不过要判断一下,注意如果使用投屏软件操作,记得在__arm__前取反。

MySlide::MySlide(QWidget *parent):
    QWidget(parent),
    curpageindex(0),
    pagecount(0),
    isdragging(false)

{
    pageicon.clear();
    this->setMinimumSize(400, 300);
    this->setAttribute(Qt::WA_TranslucentBackground, true);//半透明
    scrollarea = new QScrollArea(this);
    scrollarea->setAlignment(Qt::AlignCenter);
    mainwidget = new QWidget(this);
    mainwidget->setStyleSheet("backgroud:transparent"); //透明
    scrollarea->setWidget(mainwidget);
    bottomwidget = new QWidget(this);
    bottomwidget->setStyleSheet("background:transparent");
    bottomhbl = new QHBoxLayout();
    bottomhbl->setContentsMargins(0, 0, 0, 0);
    bottomhbl->setAlignment(Qt::AlignCenter);
    bottomwidget->setLayout(bottomhbl);
    scrollarea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏滚动条
    scrollarea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    scroller = QScroller::scroller(scrollarea);
    //arm即平板为触摸式,PC为鼠标式
#if __arm__
    QScroller::ScrollerGestureType gesture =
            QScroller::TouchGesture;
#else
    QScroller::ScrollerGestureType gesture =
            QScroller::LeftMouseButtonGesture;
#endif
    scroller->grabGesture(scrollarea, gesture);
    QScrollerProperties properties = scroller->scrollerProperties();
    properties.setScrollMetric(QScrollerProperties::SnapTime, 0.5);//翻页时间
    properties.setScrollMetric(QScrollerProperties::MinimumVelocity, 1);
    scroller->setScrollerProperties(properties);

    mainhbl = new QHBoxLayout();
    mainhbl->setContentsMargins(0, 0, 0, 0);
    mainhbl->setSpacing(0);
    mainwidget->setLayout(mainhbl);

    timer = new QTimer(this);

    connect(scrollarea->horizontalScrollBar(), &QScrollBar::valueChanged,this, &MySlide::hScrollBarValueChanged);
    connect(scroller, &QScroller::stateChanged,this, &MySlide::onStateChanged);
    connect(timer, &QTimer::timeout,this, &MySlide::onTimerTimeOut);
    connect(this, &MySlide::curPageIndexChanged,this, &MySlide::onCurrentPageIndexChanged);
}

首页:

        我决定在首页实现一些简单的功能,很常见的显示日期、时间、天气,在上方我加入了网络连接检测,日后可以考虑加入别的检测。

         这里我使用的是七段数字显示时间,使用QLCDNumber和QDateTime相结合就可以实现。使用一个QTimer设定1000,每隔1秒更新一下LCDNumber。

        如果要获得实时天气,可以向我们的老朋友心知天气api发送请求。使用QNetworkRequest向心知天气api发送请求,可以得到一条Json字符串,使用QJson解析Json即可获得天气。切换城市的话我使用弹出框,在弹出框中操作,如果在首页上操作显得不太和谐。

        检测网络连接我使用了一个简单办法,不过不是很快,仅供参考。

void HomePage::isConnect(){
    update();
    QNetworkConfigurationManager mgr;
    if(!mgr.isOnline()){
        wifiLabel->setPixmap(QPixmap(":/icons/wifi2.png"));
    }
    else{
        wifiLabel->setPixmap(QPixmap(":/icons/wifi1.png"));
    }

}

连接页:

        连接页是用来让树莓派和STM32连接的,我设置了串口、TCP、OneNET连接,平常也都是这老三样了。设置上方左右两个文本框用来接收和发送,在三种模式中通用。接受框收到的数据如果是Json字符串,会自动解析然后控制STM32。

        如果使用OneNET连接,有两种思路。一种是上位机连接OneNET接收下发命令,然后通过串口控制下位机;另一种是下位机连接OneNET接收下发命令,然后直接控制下位机。这里我使用第一种,因为方便拓展,而且连接更加稳定。

        接收到DHT11传来的数据之后,创建SQLite数据库th.db,把数据放进去以备之后使用。

数据页:

        数据页主要是用来显示数据库信息的,左侧文本框里是数据库全部信息,拥有三种搜索方法,搜索温度、搜索湿度、搜索时间。按下右下角的按钮可以选择搜索方式,搜索结果会在右侧文本框显示。如果搜索时间,则会显示选中时间及之后的所有数据。

        搜索时间之后可以点击生成折线图,然后会弹出一个框,用QtCharts的折线图显示数据。

Logo

鸿蒙生态一站式服务平台。

更多推荐