嵌入式QT开发遇到问题

一、信号槽机制下,只有头文件中加入了Q_OBJECT,你才能使用QT中的signal和slot机制。

Q:子类继承父类时,子类头文件未加入Q_OBJECT时,可以构建纯虚函数来实现子类得信号槽机制。

A:

父类函数baseWave类头文件定义纯虚函数setWavepage;

class baseWave : public QWidget
{
    Q_OBJECT
public:
    explicit baseWave(QWidget *parent = 0);
    ~baseWave();
    void virtual setWavepage() = 0;
}

子类函数waveFirst类头文件定义,必须实现setWavepage函数;

class waveFirst : public baseWave
{
    Q_OBJECT
public:
    explicit waveFirst (QWidget *parent = 0);
    ~waveFirst ();
    void setWavepage();
}

 

当子类需要实现信号槽机制时,子类函数waveFirst类头文件定义,必须实现setWavepage函数;

    connect(timerTime, SIGNAL(timeout()), this, SLOT(UpdateTime()));

*********************************分割线    Q2********************************************************

在设计界面时,遇到在一个界面时,需要多级按钮的切换。实例中,有五个按钮,实现界面的8个功能实现。8个功能分为具体的四类,每类分别实现两种功能(必须为四类)。

 案列描述:

触发按钮1(BT1)时,按钮界面能实现功能1和功能2;

触发按钮2(BT2)时,按钮界面能实现功能3和功能4;

触发按钮3(BT3)时,按钮界面能实现功能5和功能6;

触发按钮4(BT4)时,按钮界面能实现功能7和功能8;

触发按钮5(BT5)时,按钮界面能实现返回一级BT界面;

界面文件UI:

界面头文件定义,自定义槽函数,枚举BUTTON的LEVEL,定义变量m_button_level及其get和set函数:

class MainWindow : public QMainWindow
{
    Q_OBJECT
    enum {
        MENU_BUTTON_INIT = 0x00,
        MENU_BUTTON_FIRST = 0x01,
        MENU_BUTTON_SECOND= 0x02,
        MENU_BUTTON_THRID = 0x03,
        MENU_BUTTON_FOUR = 0x04,
    };
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    int button_level() const;
    void setButton_level(int button_level);

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_5_clicked();

private:
    Ui::MainWindow *ui;
    int m_button_level;
};

 cpp文件的设计:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_button_level = MENU_BUTTON_INIT;
    ui->pushButton->setText("按钮1.1");
    ui->pushButton_2->setText("按钮2.1");
    ui->pushButton_3->setText("按钮3.1");
    ui->pushButton_4->setText("按钮4.1");
    ui->pushButton_5->setText("返回");
    ui->pushButton_5->setEnabled(false);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    if(button_level() == MENU_BUTTON_INIT)
    {
        ui->pushButton->setText("功能1");
        ui->pushButton_2->setText("功能2");
        ui->pushButton_3->setText("");
        ui->pushButton_4->setText("");
        ui->pushButton_5->setText("返回");
        ui->pushButton->setEnabled(true);
        ui->pushButton_2->setEnabled(true);
        ui->pushButton_3->setEnabled(false);
        ui->pushButton_4->setEnabled(false);
        ui->pushButton_5->setEnabled(true);
        setButton_level(MENU_BUTTON_FIRST);
    }
    else if(button_level() == MENU_BUTTON_FIRST)
    {
        qDebug() << "send function 1!";
    }
    else if(button_level() == MENU_BUTTON_SECOND)
    {
        qDebug() << "send function 3!";
    }

}

void MainWindow::on_pushButton_2_clicked()
{
    if(button_level() == MENU_BUTTON_INIT)
    {
        ui->pushButton->setText("功能3");
        ui->pushButton_2->setText("功能4");
        ui->pushButton_3->setText("");
        ui->pushButton_4->setText("");
        ui->pushButton_5->setText("返回");
        ui->pushButton->setEnabled(true);
        ui->pushButton_2->setEnabled(true);
        ui->pushButton_3->setEnabled(false);
        ui->pushButton_4->setEnabled(false);
        ui->pushButton_5->setEnabled(true);
        setButton_level(MENU_BUTTON_SECOND);
    }
    else if(button_level() == MENU_BUTTON_FIRST)
    {
        qDebug() << "send function 2!";
    }
    else if(button_level() == MENU_BUTTON_SECOND)
    {
        qDebug() << "send function 4!";
    }
    else if(button_level() == MENU_BUTTON_THRID)
    {
        qDebug() << "send function 5!";
    }
}

void MainWindow::on_pushButton_3_clicked()
{
    if(button_level() == MENU_BUTTON_INIT)
    {
        ui->pushButton->setText("");
        ui->pushButton_2->setText("功能5");
        ui->pushButton_3->setText("功能6");
        ui->pushButton_4->setText("");
        ui->pushButton_5->setText("返回");
        ui->pushButton->setEnabled(false);
        ui->pushButton_2->setEnabled(true);
        ui->pushButton_3->setEnabled(true);
        ui->pushButton_4->setEnabled(false);
        ui->pushButton_5->setEnabled(true);
        setButton_level(MENU_BUTTON_THRID);
    }
    else if(button_level() == MENU_BUTTON_THRID)
    {
        qDebug() << "send function 6!";
    }
    else if(button_level() == MENU_BUTTON_FOUR)
    {
        qDebug() << "send function 7!";
    }
}

void MainWindow::on_pushButton_4_clicked()
{
    if(button_level() == MENU_BUTTON_INIT)
    {
        ui->pushButton->setText("");
        ui->pushButton_2->setText("");
        ui->pushButton_3->setText("功能7");
        ui->pushButton_4->setText("功能8");
        ui->pushButton_5->setText("返回");
        ui->pushButton->setEnabled(false);
        ui->pushButton_2->setEnabled(false);
        ui->pushButton_3->setEnabled(true);
        ui->pushButton_4->setEnabled(true);
        ui->pushButton_5->setEnabled(true);
        setButton_level(MENU_BUTTON_FOUR);
    }
    else if(button_level() == MENU_BUTTON_FOUR)
    {
        qDebug() << "send function 8!";
    }
}

void MainWindow::on_pushButton_5_clicked()
{
    if(button_level() != MENU_BUTTON_INIT)
    {
        ui->pushButton->setText("按钮1.1");
        ui->pushButton_2->setText("按钮2.1");
        ui->pushButton_3->setText("按钮3.1");
        ui->pushButton_4->setText("按钮4.1");
        ui->pushButton_5->setText("返回");
        ui->pushButton->setEnabled(true);
        ui->pushButton_2->setEnabled(true);
        ui->pushButton_3->setEnabled(true);
        ui->pushButton_4->setEnabled(true);
        ui->pushButton_5->setEnabled(true);
        setButton_level(MENU_BUTTON_INIT);

    }
}

int MainWindow::button_level() const
{
    return m_button_level;
}

void MainWindow::setButton_level(int button_level)
{
    m_button_level = button_level;
}

按钮操作显示图:

一级Button切换到四种类,8项功能切换图

 

输出Debug:

send function 1!

send function 2!

send function 3!

send function 4!

send function 5!

send function 6!

send function 8!

send function 7!

 

########################要点#######################

关键在于不同功能的类区分,用宏定义,实现对于不同功能切换时,设置Level来区分。

 

*********************************分割线    Q3********************************************************

在应用Qt的tablewidget开发时,遇到一个页面最多显示10行,总共有60个序号需要显示,这时通过切换到不同的table的page,采用双列的显示方式,具体要求见图;(tip:tablewidget基础知识我是参照这篇文章的)

 60个序号对应着,每个的索引、值、属性;每页显示20个序号,可以通过3的页面切换显示所有序号。通过button来触发页面切换,和每个索引值和属性的改变,且值设置了输入范围;(插入Line Edit参考了这边文章-- m沉默01Qt之QTableWidget详细使用,NICE,很详细!!)

头文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#define KEY_NUM_0            (Qt::Key_0)     // 0
#define KEY_NUM_1            (Qt::Key_1)     // 1
#define KEY_NUM_2            (Qt::Key_2)     // 2
#define KEY_NUM_3            (Qt::Key_3)     // 3
#define KEY_NUM_4            (Qt::Key_4)     // 4
#define KEY_NUM_5            (Qt::Key_5)     // 5
#define KEY_NUM_6            (Qt::Key_6)     // 6
#define KEY_NUM_7            (Qt::Key_7)     // 7
#define KEY_NUM_8            (Qt::Key_8)     // 8
#define KEY_NUM_9            (Qt::Key_9)     // 9
#define KEY_UP            (Qt::Key_Up)
#define KEY_DOWN          (Qt::Key_Down)
#define KEY_LEFT          (Qt::Key_Left)
#define KEY_RIGHT         (Qt::Key_Right)
#define KEY_CONFIRM       (Qt::Key_Return)
#include <QMainWindow>
#include <QTableWidget>
#include <QKeyEvent>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void initNetWidget();
    void showTableIndex(int index);
    void netSelectItem(int row, int column);
    void netUpdateRedeployWave(unsigned char row, unsigned char cloumn);
protected slots:
    void keyPressEvent(QKeyEvent * event);

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

private:
    Ui::MainWindow *ui;
    int m_netRow;
    int m_netColumn;
    int m_columId;
    int m_pageIndex;
};

#endif // MAINWINDOW_H

cpp文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QLineEdit>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_columId = 1;
    m_pageIndex = 0;
    initNetWidget();

}

MainWindow::~MainWindow()
{
    delete ui;
}
//初始化tablewidget
void MainWindow::initNetWidget()
{
    ui->tableWidget->setFocusPolicy(Qt::NoFocus);
     ui->tableWidget->setVerticalScrollBarPolicy(
                Qt::ScrollBarAlwaysOff);
     ui->tableWidget->setHorizontalScrollBarPolicy(
                Qt::ScrollBarAlwaysOff);
     ui->tableWidget->setEditTriggers(
                QAbstractItemView::NoEditTriggers);

     ui->tableWidget->setSelectionMode(
                QAbstractItemView::SingleSelection);
     ui->tableWidget->setGridStyle(Qt::DotLine);
     ui->tableWidget->horizontalHeader()->setStyleSheet(
                 "QHeaderView::section{background:skyblue;}");
     ui->tableWidget->verticalHeader()->setVisible(false);
    //设置不同页面默认选择项
    m_netRow = m_pageIndex*10;
    m_netColumn = 1;
    netSelectItem(0,1);
     showTableIndex(m_pageIndex);
}
//根据m_pageIndex的范围0-2,来显示其中10行
void MainWindow::showTableIndex(int index)
{
    int tIndex = 0;
     for(tIndex;tIndex < ui->tableWidget->rowCount();tIndex ++)
    {
        ui->tableWidget->setRowHidden(tIndex, true);
    }
     tIndex = index*10;

    for(tIndex;tIndex <(index+1)*10;tIndex ++)
   {
        //显示tIndex行
       ui->tableWidget->setRowHidden(tIndex, false);
       //限制文本输入范围
       QRegExp rx("[1-9]|[1-5][0-9]|6[0]");
       QRegExpValidator *pReg = new QRegExpValidator(rx,this);

       QLineEdit *line_1 = new QLineEdit();
       QLineEdit *line_2 = new QLineEdit();
       //lineEdit设为noFocus
       line_1->setFocusPolicy(Qt::NoFocus);
       line_2->setFocusPolicy(Qt::NoFocus);

       line_1->setPlaceholderText("输入范围1-60:");
       line_2->setPlaceholderText("输入范围1-60:");

       line_1->setValidator(pReg);
       line_2->setValidator(pReg);
        //tablewidget item插入lineEdit
       ui->tableWidget->setCellWidget(tIndex,1,line_1);
       ui->tableWidget->setCellWidget(tIndex,4,line_2);
   }

}
//设置默认的item索引
void MainWindow::netSelectItem(int row,int column)
{
    ui->tableWidget->clearSelection();
    m_netRow = row;
    m_netColumn = column;
    ui->tableWidget->item(row,column)->setSelected(true);

}
//键盘按键触发事件
//0-9可以选择不同的行
//上下左右切换到不同的item
void MainWindow::keyPressEvent(QKeyEvent *event)
{
    switch(event->key()) {
        case KEY_NUM_1:
            netSelectItem(0+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_2:
            netSelectItem(1+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_3:
            netSelectItem(2+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_4:
            netSelectItem(3+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_5:
            netSelectItem(4+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_6:
            netSelectItem(5+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_7:
            netSelectItem(6+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_8:
            netSelectItem(7+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_9:
            netSelectItem(8+10*m_pageIndex,m_netColumn);
            break;
        case KEY_NUM_0:
            netSelectItem(9+10*m_pageIndex,m_netColumn);
            break;
        case KEY_UP:
             m_netRow =10*m_pageIndex+
                                             (m_netRow%10+9) %10;
            netSelectItem(m_netRow,  m_netColumn);
            break;
        case KEY_DOWN:
            m_netRow =10*m_pageIndex+
                                            (m_netRow%10+1) %10;
            netSelectItem(m_netRow,m_netColumn);
            break;
        case KEY_LEFT:
        case KEY_RIGHT:
            if(m_columId == 1)
            {
                netSelectItem(m_netRow,4);
                m_columId = 4;
            }
            else
            {
                netSelectItem(m_netRow,1);
                m_columId = 1;
            }
            break;
        case Qt::Key_Enter:
        case KEY_CONFIRM:               //回车键来实现LineEdit与主窗口焦点的切换
            if(ui->tableWidget->cellWidget(m_netRow,m_netColumn)->hasFocus())
            {
                this->setFocus();
            }
            else
            {
                ui->tableWidget->cellWidget(m_netRow,m_netColumn)->setFocus();
            }
            break;
        default:
            break;
    }
}
//更改当前item的属性
void MainWindow::netUpdateRedeployWave(
        unsigned char row,
        unsigned char cloumn)
{
    if(ui->tableWidget->item(row,cloumn)->text().compare(QStringLiteral("是")) == 0)
    {
        ui->tableWidget->item(row,cloumn)->setText(
                   QStringLiteral("否"));
    }
    else
    {
        ui->tableWidget->item(row,cloumn)->setText(
                   QStringLiteral("是"));
    }

}
//更改item属性
void MainWindow::on_pushButton_clicked()
{
    netUpdateRedeployWave(m_netRow,m_columId+1);
}
//bt2和bt3切换页面
void MainWindow::on_pushButton_2_clicked()
{
    m_pageIndex = (m_pageIndex+2)%3;
    m_netRow = m_netRow%10+10*m_pageIndex;
    netSelectItem(m_netRow,m_netColumn);
    showTableIndex(m_pageIndex);}

void MainWindow::on_pushButton_3_clicked()
{
    m_pageIndex = (m_pageIndex+1)%3;
    m_netRow = m_netRow%10+10*m_pageIndex;
    netSelectItem(m_netRow,m_netColumn);
    showTableIndex(m_pageIndex);
}

OK,这个基本差不多了。

运行后的界面:

文本输入可以通过Enter键来获取item的焦点,输入1-60的整数即可;回车之后还可以通过0-9来快捷访问不同的item;右侧的按键也可以翻页及修改属性值:

 

########################要点#######################

对tablewidget基本函数的了解;上下左右进行切换不同item时,注意不同页面的item范围不一致;在第一页时,m_pageIndex =0,item最小值 m_netRow = m_netRow%10+10*m_pageIndex;在tablewidget item插入控件时,需要设置控件的focuspolicy为NoFocus,这样不会让父类失去焦点。

*********************************分割线    Q4********************************************************

    在使用QT按键时,进行按键触发响应事件,等待业务(应答)应答过程中,可以通过加入定时器过度中间过程。可能出现业务无应答,可以通过定时器超时,将状态及按键进行初始化;在定时器执行过程中,有业务应答回应,可以停止定时器,从而进入到下一个业务状态。

代码实现为:

.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void InitTimer(int time=10);
private slots:
    void on_bt1_clicked();
    void recvMsg(int flag);
    void TimerTimeOut();
private:
    Ui::MainWindow *ui;
    QTimer *m_timer;
    int m_status;
};
#endif // MAINWINDOW_H

.cpp文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include<QKeyEvent>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_timer = new QTimer(this);
    m_status = 0;
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::InitTimer(int time)
{
    if(NULL == m_timer)
    {
        m_timer = new QTimer(this);
    }
    m_timer->setSingleShot(false);
    m_timer->start(time*1000);
    connect(m_timer,SIGNAL(timeout()),
            this,SLOT(TimerTimeOut()));
}
void MainWindow::on_bt1_clicked()
{  
    if(m_status == 0)
    {
        InitTimer(5);
        ui->bt1->setText("参数配置中");
        qDebug() << "状态1下,启动定时器!";
    }
    else if(m_status == 1)
    {
        InitTimer(5);
        ui->bt1->setText("取消配置中");
        qDebug() << "状态2下,启动定时器!";
    }
}

void MainWindow::recvMsg(int flag)
{
    qDebug() << "Recv Response";
    if(m_timer->isActive())
    {
        m_timer->stop();
        qDebug() << "业务配置成功/失败!";
    }
    m_status = flag;
    switch flag:{
        case 1:    //success
            qDebug() << "业务配置成功!";
            ui->bt1->setText("业务中");
            break;
        case 0:    //failed
            qDebug() << "业务配置失败!";
            ui->bt1->setText("参数配置");
            break;
        defalut:
            break;
    }
    
}
void MainWindow::TimerTimeOut()
{
    ui->bt1->setText("参数配置");
    qDebug() << "业务配置超时,返回状态1!";
    m_status = 0;

}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nobSlience

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值