QT(二):Qt相关控件的使用和设置,Qt对话框的使用,画图事件的创建和设置,线程和锁的创建利用,网络编程,TCP和UDP客户端及服务器的创建,SQLITE数据库,QTableWidget控件的使用

一、相关控件及操作配置

1、QPushButton & QtoolButton(按钮)

    setText(QString)  ---- 设置按钮上的内容
    setFixedSize(int w, int h) --- 设置固定大小
    setFixedHeight(int)    --- 设置固定高度
    setFixedwidth(int)    --- 设置固定宽度
    setMaximumSize(int w, int h);   ---- 设置最大宽高
    setMinimumSize(int w, int h);   ---- 设置最小宽高
    setFont(QFont)     ---- 设置字体
    setIcon(QIcon)  --- 设置图标
    setIconSize(QSize)   --- 设置图标大小
    setFlat(bool)   --- 设置是否透明
    setEnabled(bool)   --- 设置是否可用
    toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon)
    signals:
        clicked()   --- 点击信号
        pressed()   --- 按下信号
        released()  --- 松开信号

2、QLabel (标签)

    setText(QString);  --- 设置内容
    setPixmap(QPixmap);  --- 显示图片
    setAlignment();  --- 设置对齐方式
    setScaledContents(bool) --- 设置自适应
    添加资源:
        右键headers添加新文件 --> Qt Resource file(Qt 资源文件) ---> location(资源存放位置)
        ---> 添加前缀 -->添加文件
    打开资源:
        右键资源选择:open in editor    
        
 

3、布局

QHBoxLayout  ---- 水平布局
        addWidget(QWidget *)  --- 添加控件
        addLayout(QLayout *)  --- 添加布局
    QVBoxLayout  ---- 垂直布局
        addWidget(QWidget *)  --- 添加控件
        addLayout(QLayout *)  --- 添加布局
    QGridLayout  ---- 网格布局
        addWidget(QWidget *, 第几行 第几列 占几行 占几列) //行/列是0 base的

4 、QLineEdit(行编辑框)


    QString text()  ---- 获取行编辑器的内容
    setText(QString)  --- 设置内容
    setReadOnly(bool)  --- 设置是否只读
    setAlignment(Qt::AlignRight)  --- 设置对齐方式
    setEchoMode();   --- 设置显示模式

5 、QTextEdit(文本编辑器)


    QString toHtml();   --- 获取带格式的文本
    QString toPlainText();  --- 获取纯文本
    setText(QString);  --- 设置内容     
    

6、 QRadioButton(单选按钮)


    signals:
        clicked()
     

7 、QGroupBox(分组框)


    setTitle -- 设置标题
    setLayout  --- 添加布局
    

8、QCheckBox复选框
    

signals:
        clicked()
    bool isChecked()  --- 获取是否被勾选

9、QComBoBox下拉列表
    

addItem(QString)   --- 添加条目
    addItems(QStringList)  --- 添加一堆条目
    signals:
        currentIndexChanged(int)  ---  当index改变时触发   
        currentIndexChanged(QString)   
     
    

10、 QStackWidget堆叠窗口
    

addWidget()   --- 添加子页面
    setCurrentIndex(int)  --- 翻到该页面
    int currentIndex()  --- 获取当前页面
    count()  --- 获取总页面数

   

11、QSpinBox
   

12、QDoubleSpinBox数字设定框
    

setValue(double)  --- 设置值
    double value()    --- 获取值
    setRange(double min, double max) --- 设置范围
    setSingleStep(double)  --- 设置步长
    setPrefix(QString)  --- 设置前缀
    setSuffix(QString)  --- 设置后缀 
    setDecimal(int)   --- 设置精度(小数位数)
    signals:
        valueChanged(int); valueChanged(QString) ;  //QSpinBox
        valueChanged(double); valueChanged(QString) ;  //QDoubleSpinBox
         

   

13、 QSlider: 滑动条
    

setValue(int) //设置特定的值
    int value()   //获取当前值
    setRange(int, int); //设置范围
    setOrientation(Qt::Horizontal)  --- 水平放置   Vertical --- 垂直的
    signals:
        valueChanged(int) ;  

   

14、 QScrollBar:滚动条
   

setValue(50);
    setRange(0, 100);
    setOrientation(Qt::Horizontal);    
    signals:
        valueChanged(int) ;  

    

15、 QProgressBar:进度条
    

setValue(int)
    setRange(int, int);

16、 QTimer: 定时器

    start(int msec);   --- 启动定时器,设置超时时间,单位:毫秒
    stop();  --- 停止定时器
    signals:
        timeout();   --- 超时信号
 

二、对话框
    

StandardDialog:


    1、模态对话框:
        

QDialog dialog(this);
        dialog.resize(300, 200);
        //当使用QDialog::exec()成员函数的时候,弹出的对话框是模态对话框,会阻止用户的输入,直到用户关闭它
        dialog.exec();
    
   

2、非模态对话框:
      

 QDialog *dialog = new QDialog(this);
        //设置属性,当用户关闭该对话框的时候在删除整个对象
        dialog->setAttribute(Qt::WA_DeleteOnClose);
        dialog->resize(300, 200);
        //当使用QDialog::show()成员函数的时候,弹出的对话框是非模态对话框,不会阻止用户的输入
        dialog->show();
    
   

3、QFileDialog: 文件对话框
        

静态函数
        getOpenFileName();
        getOpenFileNames();
        getExistingDirectory();
        QString fileName = QFileDialog::getOpenFileName(this, "打开文件", ".", "文本文件 (*.h *.cpp *.txt)");
        QStringList fileNames = QFileDialog::getOpenFileNames(this, "打开文件", ".", "文本文件 (*.h *.cpp *.txt)");

  4、QMessageBox: 消息框      

静态函数
        question();
        warning();
        information();
        about();
        aboutQt();
        
        QMessageBox msgBox;
        msgBox.setText("请确保您的数据准确.");
        msgBox.setInformativeText("确定要提交您的个人信息吗?");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        msgBox.setDefaultButton(QMessageBox::Yes);
        int ret = msgBox.exec();
        switch (ret)
        {
            case QMessageBox::Yes:
                this->close();
                break;
            default:
                break;
        }
        
 

5、 QInputDialog: 输入对话框

        QInputDialog::getDouble
        QInputDialog::getText();
        QInputDialog::getInt();
        double num = QInputDialog::getDouble(this, "获得一个浮点数", "请输入一个浮点数:", 100, 0, 100, 5); 
   

6、QErrorMessage: 错误对话框  

     QErrorMessage *errMsg = QErrorMessage::qtHandler();
        //errMsg->setAttribute(Qt::WA_DeleteOnClose);
        errMsg->showMessage("this is a system error");
        errMsg->showMessage("this is a array overflow error");

        errMsg->showMessage("this is a system error");
        errMsg->showMessage("this is a array overflow error");

    7、QFontDialog: 字体对话框        

QFontDialog::getFont();
        static QFont originaIFont = ui->textEdit->font();//获取初始字体
            bool isOk;
            QFont font = QFontDialog::getFont(&isOk, this);
            if (isOk)
            {
                te->textEdit->setFont(font);
            }
            else
            {
                te->textEdit->setFont(originalFont);
            }
   

8、QColorDialog: 颜色对话框
 

       QColorDialog::getColor();
        QColor color = QColorDialog::getColor();

三、QMainWindow设置

QMenuBar:菜单栏
    QMenu: 菜单
    QAction: 动作
    
    QToolBar: 工具栏
    QStatusBar: 状态栏
    
    setWindowTitle("主窗口");
    //: + 前缀 + 文件名
    setWindowIcon(QIcon(":/mw_images/10.png"));
    resize(640, 480);

    //一个主窗口只能有一个菜单栏
    QMenuBar *menuBar = this->menuBar();
    //可以增加多个菜单
    //QMenu *fileMenu = menuBar->addMenu(QIcon(":/mw_images/file.png"), "文件");
    QMenu *fileMenu = menuBar->addMenu("文件");
    QMenu *editMenu = menuBar->addMenu("编辑");
    QMenu *setMenu = menuBar->addMenu("设置");

    //一个菜单可以增加多个菜单项
    openAct = fileMenu->addAction(QIcon(":/mw_images/open.png"), "打开文件");
    fileMenu->addSeparator();
    closeAct = fileMenu->addAction(QIcon(":/mw_images/close.png"), "关闭文件");

    //增加工具栏,一个主窗口可以有多个工具栏
    QToolBar *fileTool = this->addToolBar("文件");
    fileTool->addAction(openAct);
    fileTool->addAction(closeAct);
    fileTool->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
    fileTool->setFloatable(true);
    fileTool->setMovable(true);
    //每个工具栏可以有多个工具项
    QToolBar *editTool = this->addToolBar("编辑");
    editTool->addAction(copyAct);
    editTool->addAction(pasteAct);
    QToolBar *setTool = this->addToolBar("设置");
    setTool->addAction(fontAct);
    setTool->addAction(colorAct);

    //一个主窗口可以有多个滑动窗口
    QDockWidget *dw1 = new QDockWidget("滑动窗口");
    dw1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    //设置dw1成为一个独立的窗口
    dw1->setFloating(false);
    //增加一个滑动窗口
    addDockWidget(Qt::LeftDockWidgetArea, dw1);

    //一个主窗口只能有一个中央部件
    te = new QTextEdit;
    te->setFixedSize(640, 480);
    setCentralWidget(te);

    //一个主窗口只能有一个状态栏
    QStatusBar *statBar = this->statusBar();
    lb_status = new QLabel;
    lb_status->setText("xxx file is editing... ");
    prog_bar = new QProgressBar;
    prog_bar->setValue(67);
    statBar->addWidget(lb_status);
    statBar->addWidget(prog_bar);

    

四、事件        

//事件处理的统一的入口
        bool event(QEvent *event);
        
        //特定事件处理器
        void mousePressEvent(QMouseEvent *e);  --- 鼠标按下事件
            e->button();  --- 获取鼠标按键
                Qt::LeftButton(); --- 左键
                Qt::RightButton();  --- 右键
            e->pos();   --- 获取该界面鼠标坐标
            e->x();     --- 获取该界面鼠标的x坐标
            e->y();
            e->globalPos();  --- 获取全局界面(屏幕)鼠标坐标
            e->globalX(); 
            e->globalY();
        void mouseReleaseEvent(QMouseEvent *e);  --- 鼠标松开事件
        void mouseMoveEvent(QMouseEvent *e);     --- 鼠标移动事件
        void mouseDoubleClickEvent(QMouseEvent *e); --- 鼠标双击事件
        void wheelEvent(QWheelEvent *e);  --- 滚轮事件
            e->angleDelta();
            e->delta();    --- 获取滚轮增量
        void keyPressEvent(QKeyEvent *e);  --- 按键按下事件
            e->key(); --- 获取按键
                Qt::Key_A
                Qt::Key_0
                Qt::Key_Up;
                Qt::Key_Return/Qt::Key_Enter
        void keyReleaseEvent(QkeyEvent *e);  --- 按键松开事件
        void timerEvent(QTimerEvent *e);   --- 定时器时间
            startTimer(int ms);
            
        void Widget::paintEvent(QPaintEvent *event) //绘图事件    

 事件过滤器
    

1) 安装事件过滤器


        le->installEventFilter(this);  //从QObject继承出来的对象,可以注册一个事件过滤器,所有的事件先交给事件过滤器处理
             
  

 2) 重写事件过滤器
  

 /*
    参数: 
        watched: 对象
        event: 事件
    返回值:
        true: 事件已处理
        false: 事件未处理
    */
    bool Widget::eventFilter(QObject *watched, QEvent *event)
    {
        if (event->type() == QEvent::KeyPress)
        {
            //通过watched判断是否是关注的对象产生了事件
            //通过event判断是否是关注的事件产生了
            //如果是想要关注的对象产生了想要关注的事件则进行处理,处理完毕返回true
            
            QKeyEvent *keyEvent = static_cast(event);
            if (keyEvent->key() >= Qt::Key_0 && keyEvent->key() <= Qt::Key_9)
            {
                qDebug() << (char)(keyEvent->key());
                QString tmp = ui->te2->toPlainText();
                tmp += QString(QChar(keyEvent->key()));
                ui->te2->setText(tmp);
                return true;//返回true意味这事件处理完毕,这个事件不会再继续处理
            }
        }  

        //对于不关心的事件,记得最后要调用基类的事件处理函数,维持原本的行为
        //让基类按照常规处理,一定要加上
        return QWidget::eventFilter(watched, event);
    }    
 

五、绘图
    

void Widget::timerEvent(QTimerEvent *event)
    void Widget::paintEvent(QPaintEvent *event);
    update() --- 手动刷新,界面重绘,触发paintEvent事件,可以配合定时器事件timerEvent一起使用

画家事件,画笔,画刷    


    QPainter: //画家
    QPen: //笔
    QBrush: //刷子
    
    QPainter p(this);//set this 表示设置主窗口为画布
    
    QPen pen(QColor(0, 0, 255));
    pen.setWidth(3);
    pen.setStyle(Qt::DashLine);
    p.setPen(pen); //设置画笔
    
    QBrush brush(QColor(255, 0, 0));
    brush.setStyle(Qt::Dense3Pattern);
    p.setBrush(brush);    //设置画刷
 
    p.drawLine(0, 0, 100, 100);//画线
    p.drawRect(100, 100, 200, 100);  //画矩形
    p.drawEllipse(QPoint(300, 300), 100, 50); //画椭圆
    p.drawEllipse(QPoint(450, 300), 100, 100); //画圆
    p.drawPixmap(xPos++*50, 400, QPixmap(":/pic/luffy.png")); //画图片

    
    p.translate(width()/2, height()/2); //将画家的坐标系的原点移动到主窗口的中心点位置
    p.drawEllipse(QPoint(0, 0), 150, 150);
    p.save(); //保存当前的画家的坐标系
    //画秒针
    p.rotate(6); //将画家的坐标系顺时针旋转6°
    p.drawLine(QPoint(0, 0), QPoint(0, -100));
    p.restore();    //恢复之前保存的画家的坐标系     

文件操作:文件类 QFile    
    

QFile file(filename);
    file.exists()
    file.setFileName(filename1);
    file.fileName()
    file.bytesAvailable()
    file.size()
    file.copy("2.txt")
    file1.errorString()
    bool file.open();   --- 打开文件
        QIODevice::ReadOnly
        QIODevice::WriteOnly
        QIODevice::ReadWrite
        QIODevice::Trancate
        QIODevice::Text
    file.atEnd();   ---判断是否到达文件末尾
    file.read();    --- 按字节读取文件内容
    file.readLine(); --- 读取一行
    file.readAll();  --- 读取所有内容
    file.write();  --- 写入内容
    file.close();  --- 关闭文件  
    

线程和锁    

QThread & QMutex
    //继承QThread类,重写run方法
    start() --- 启动线程
    terminate() --- 终止线程
    
    QMutex: 互斥锁
    lock(); --- 加锁
    unlock(); --- 解锁    
    
    QMutex mutex;
    //要使用QThread,一般可以新建自己的类,继承与QThread
    MyThread::MyThread(QObject *parent) : QThread(parent)
    {

    }
    //重写QThread的run()函数,线程要做的事情就是在run()函数里处理
    void MyThread::run()
    {
        while(1)
        {
            mutex.lock(); //进入临界区前,加锁
            for (int i = 0; i < 10; i++)
            {
                std::cout << intArray[i] << " ";
            }
            std::cout << std::endl;
            mutex.unlock();//退出临界区,解锁,确定同时只有一个线程处理公共资源
        }
    }

六、网络编程
    

UPD/TCP网络编程
    
    qmake: QT += network

 一、UDP连接
    

UDP: QUdpSocket
    

##UDP客户端

//创建套接字
    socket = new QUdpSocket(this);

    //连接数据到达信号和槽函数
    //QUdpSocket::readyRead
    connect(socket, &QUdpSocket::readyRead, this, &Widget::data_ready_handler);

    //当前存在没有处理数据包
    while (socket->hasPendingDatagrams())
    {
        QByteArray datagram;
        //根据数据报的大小调节接收的字节数组的大小
        datagram.resize(socket->pendingDatagramSize());
        //接收套接字的数据到字节数组
        socket->readDatagram(datagram.data(), datagram.size());

        //将内容追加到接收区的文本编辑框中
        ui->te_receive->append(QString::fromLocal8Bit(datagram));
    }    
    
    //发送数据报到服务器端,指定服务器的IP地址和端口
    if (socket->writeDatagram(ui->te_send->toPlainText().toLocal8Bit(), QHostAddress(ip), port.toUShort()) == -1)
    {
        qDebug() << "发送数据失败";
    }
    else
    {
        qDebug() << "发送数据成功";
    } 
    

##UDP服务器端

//创建服务器的套接字
    socket = new QUdpSocket(this);
    //服务器绑定IP地址和端口, 唯一的服务器比客户端多的一个步骤
    socket->bind(QHostAddress::AnyIPv4, 8888);
    
    //发送数据报到客户端
    if (socket->writeDatagram(ui->te_send->toPlainText().toLocal8Bit(), ip, port) == -1)
    {
        qDebug() << "发送数据失败";
    }
    else
    {
        qDebug() << "发送数据成功";
    }    
    
    //读取数据报的数据,同时获取客户端的IP地址和指针,方便发送回数据给客户端
    socket->readDatagram(datagram.data(), datagram.size(), &ip, &port);    

二、TCP连接

TCP: QTcpServer | QTcpSocket

##TCP客户端    

socket = new QTcpSocket(this);

    //连接成功信号
    connect(socket, &QTcpSocket::connected, [=](){
        ui->pb_connect->setText("断开连接");
        ui->pb_send->setEnabled(true);
    });
    //连接断连信号
    connect(socket, &QTcpSocket::disconnected, [=](){
        ui->pb_connect->setText("连接");
        ui->pb_send->setEnabled(false);
    });
    //数据就绪信号
    connect(socket, &QTcpSocket::readyRead, [=](){
        QByteArray data = socket->readAll();
        //QString tmp = ui->te_receive->toPlainText();
        ui->te_receive->append(QString::fromLocal8Bit(data));
    });    
    
    //连接到服务器,使用服务器的IP地址和端口
    socket->connectToHost(QHostAddress(ip), port.toUShort());
    
    //发送数据到服务器
    if (socket->write(ui->te_send->toPlainText().toLocal8Bit()) == -1) //使用toLocal8Bit可以支持中文
    {
        qDebug() << "客户端发送数据失败";
    }
    else
    {
        qDebug() << "客户端发送数据成功";
    }

    //发送数据到服务器
    QByteArray data = socket->readAll();
    ui->te_receive->append(QString::fromLocal8Bit(data));    //使用fromLocal8Bit可以支持中文 
    

##TCP服务器端    

//创建TCP服务器对象
    server = new QTcpServer(this);
    //设置监听的IP地址和端口
    server->listen(QHostAddress::AnyIPv4, 8888);

    //新连接信号
    connect(server, &QTcpServer::newConnection, [=](){
        if (server->hasPendingConnections())//如果有待处理的新连接
        {
            socket = server->nextPendingConnection();//处理新连接, 获得通信套接字,以后双方的通信基于此套接字,每个新连接会产生一个新的通信套接字
        }
        
        //断连的信号
        connect(socket, &QTcpSocket::disconnected, [=](){
           ui->pb_send->setEnabled(false);
        });
        //接收数据就绪信号
        connect(socket, &QTcpSocket::readyRead, [=](){
            //读取接收到的数据
            QByteArray data = socket->readAll();
            ui->te_receive->append(QString::fromLocal8Bit(data));
        });
    });    
 
    //发送数据到客户端
    if (socket->write(ui->te_send->toPlainText().toLocal8Bit()) == -1)
    {
        qDebug() << "服务器发送数据失败";
    }
    else
    {
        qDebug() << "服务器发送数据成功";
    }

七、SQLITE数据库

 SQLITE 数据库编程
    
    qmake: QT += sql

    使用到的类:
    QSqlDatabase  //数据库连接
    QSqlQuery     //数据SQL语句执行
 

 //创建SQLITE数据库连接


    //不指定数据库连接的名字, 数据库连接缺省的名字为 "qt_sql_default_connection"
    QSqlDatabase db_student = QSqlDatabase::addDatabase("QSQLITE");//使用SQLITE数据库, 数据库连接缺省的名字为 "qt_sql_default_connection"
    
    //指定数据库连接的名字为"my_db_connection"
    QSqlDatabase db_student = QSqlDatabase::addDatabase("QSQLITE", "my_db_connection");//使用SQLITE数据库, 指定数据库连接的名字为"my_db_connection"

//设置数据库的文件名
    

db_student.setDatabaseName(db_file_name);
    
  

 //打开数据库
  

 if (!db_student.open())
    {
        qDebug() << "打开数据库失败1";
    }    
    
    

//关闭数据库    

db_student.close();

    

//使用当前的数据库连接 执行SQL操作

    QSqlQuery query(db_student); //指定一个数据库的连接
    
    QSqlQuery query;  //不指定数据库连接, 它会使用缺省的数据库连接 "qt_sql_default_connection"  
    

//创建表

    QString queryStr = "create table Student (id varchar(64) PRIMARY KEY, name varchar(64), gender varchar(64), age int)";
    if (!query.exec(queryStr))
    {
        qDebug() << "创建数据库表失败";
        qDebug() << query.lastError().text();
    }    

//数据插入   

//数据插入方式1
    queryStr = "insert into Student values('2309250001', '张三', '男', 13)";
    if (!query.exec(queryStr))
    {
        qDebug() << "插入数据失败";
        qDebug() << query.lastError().text();
    }
    
    //数据插入方式2
    queryStr = "insert into Student values(?,?,?,?)";
    query.prepare(queryStr);
    query.addBindValue("2309250002");
    query.addBindValue("李四");
    query.addBindValue("男");
    query.addBindValue(12);
    if (!query.exec())
    {
        qDebug() << "插入数据失败2";
        qDebug() << query.lastError().text();
    }    
    
    //数据插入方式3
    QString queryStr = "insert into Student values(:id,:name,:gender,:age)";
    query.prepare(queryStr);
    query.bindValue(":id", ui->le_id->text());
    query.bindValue(":name", ui->le_name->text());
    query.bindValue(":gender", ui->cbb_gender->currentText());
    query.bindValue(":age", ui->le_age->text().toInt());
    if (!query.exec())
    {
        qDebug() << "execute " << queryStr << " failed";
        qDebug() << query.lastError().text();
    }
    
    

//查询数据

    QString queryStr = "select * from Student";
    if (!query.exec(queryStr))
    {
        qDebug() << "execute " << queryStr << " failed";
        qDebug() << query.lastError().text();
    }    
    
    QString queryStr = "select * from Student where id = :id";
    query.prepare(queryStr);
    query.bindValue(":id", ui->le_id->text());
    if (!query.exec())
    {
        qDebug() << "execute " << queryStr << " failed";
        qDebug() << query.lastError().text();
    }
    while (query.next())
    {
        ui->le_name->setText(query.value(1).toString());
        ui->cbb_gender->setCurrentText(query.value(2).toString());
        ui->le_age->setText(query.value(3).toString());
    }    
    
    

//修改数据

    QString queryStr = "update Student set name=?, gender=?,age=? where id=?";
    query.prepare(queryStr);
    query.addBindValue(ui->le_name->text());
    query.addBindValue(ui->cbb_gender->currentText());
    query.addBindValue(ui->le_age->text());
    query.addBindValue(ui->le_id->text());
    if (!query.exec())
    {
        qDebug() << "execute " << queryStr << " failed";
        qDebug() << query.lastError().text();
    }    

    

//删除数据

    QString queryStr = "delete from Student where id = :id";
    query.prepare(queryStr);
    query.bindValue(":id", ui->le_id->text());
    if (!query.exec())
    {
        qDebug() << "execute " << queryStr << " failed";
        qDebug() << query.lastError().text();
    }   

八、 QTableWidget控件

//设置显示为4列
    ui->tableWidget->setColumnCount(4);

    QStringList list;
    list << "学号" << "姓名" << "性别" << "年龄";
    ui->tableWidget->setHorizontalHeaderLabels(list);
 
    //根据数据库的记录的条数来设置行数
    ui->tableWidget->setRowCount(lists.size());

    //设置tableWidget的某一项
    ui->tableWidget->setItem(i, j, (new QTableWidgetItem(lists.at(i).at(j))));    
    
    //获得某一项
    QTableWidgetItem *item = ui->tableWidget->item(i, 0);
    
    //获得行数
    int row = ui->tableWidget->rowCount();
    
    //插入1行, 0 base
    ui->tableWidget->insertRow(row);
    
    //获得某一项的数据
    ui->tableWidget->item(row, count++)->data(0).toString();
    ui->tableWidget->item(row, count++)->data(0).toInt();    
    
    //获得当前选中的行 0 base
    ui->tableWidget->currentRow();
    
    //设置id不能被用户编辑
    QTableWidgetItem *item = ui->tableWidget->item(i, 0);
    item->setFlags(item->flags() & (~Qt::ItemIsEditable));

你可能感兴趣的:(qt,开发语言,网络,数据库)