Qt常用控件\机制

  1. 按钮类
	1.1 QPushButton
	1.2 QToolButton
	1.3 QRadioButton

1.QRadioButton的Aotuexclusive属性(默认被勾选)自动排外,有且只有一个QRadio被Clicked。SetChecked(bool)可以设置手动排外。

  1. item
	2.1 QWidget
  1. 容器类
	3.1 QStackWidget
	3.2 QWidget
	3.3 QFrame (可带边框)
	3.4 ToolBox(卡包式)
  1. 编辑类
	4.1 QCombox
	4.2 QLineEdit
	4.3 QTextEdit
  1. 显示类
	5.1 QLabel
	5.2 QLcdNumber
	5.3 QProgressBar

布局

	1. 水平 QHBoxLayout
	2. 垂直 QVBoxLayout
	3. 网格
	4. 详细-布局属性
	5. 大小策略(Fixed固定,ExPanding扩张,Font字体,Min\MaxSize)
	6. 容器(分类)
	7. 弹簧 QSpacerItem

自定义控件

	a) ui的控件和自定义控件的父类要相同
	b) 选中ui控件-提升

常用事件处理

	1) app.exec() :  一直等待事件发生
	2) eventFilter():  首先经过事件过滤器   -> 转发给各个控件
	3) event(): 每个控件有本身的event() -> 调用各自的事件处理函数(一般重写派生类,写对应的虚函数比较安全)

对窗口画图

重构Widget::paintEvent
	1.在窗口部件第一次显示时,系统会自动产生一个绘图事件,从而强制绘制这个窗口部件。
    2.当重新调整窗口部件的大小时,系统也会产生一个绘制事件。
    3.当窗口部件被其他窗口部件遮挡,然后又再次显示出来的时候,就会对那些隐藏的区域产生一个绘制事件。
    4.同时可以调用QWidget::update()或者QWidget::repaint()来强制产生一个绘制事件。

重构keyPressEvent限制TextEdit输入

1.新建C++类(基类可选择QWidget,之后手动修改成QTextEdit)  ->继承
2.重构虚函数 protected:  ->重构
						void keyPressEvent
						
void TcpWriteText::keyPressEvent(QKeyEvent *ev)
{
    if(ev->key() >= Qt::Key_G && ev->key() <= Qt::Key_Z )
    {

    }
    else
    {
        QTextEdit::keyPressEvent(ev);
    }
}

3.提升为自定义控件,选择基类,输入类名,添加,设为全局,提升。

PS:使用KeyPressEvent时,要先获取焦点(有多种获得焦点方式)
setFocusPolicy(Qt::ClickFocus)//单击获取焦点

正则表达式限制LineEdit输入

#include <QValidator> 

QRegExp regx("[0-9]+$");
QPointer<QValidator> pQValidator = new QRegExpValidator(regx,ui->LECustomTime);
ui->LECustomTime(LineEdit)->setValidator(pQValidator);

正则表达式去除字符串中的换行符

QStringList  <<  Filetxt.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);

判断第三点在向量的左还右

/* 
 * a0:向量起点
 * a1:向量方向上的一点
 * a2:第三点
 */
int ispostive(MyPoint a0,MyPoint a1,MyPoint a2)
{
    double result = (a0.PointX - a2.PointX)*(a1.PointY - a2.PointY) - (a0.PointY - a2.PointY)*(a1.PointX - a2.PointX);
    if(result >0)
    {
        cout << "在左";
        return 1;//在左
    }else if(result <0)
    {
        cout << "在右";
        return -1;//在右
    }else
    {
        cout << "共线";
        return 0;//共线
    }
}

返回相交线段之间的夹角

/*
 * a0:线段1起点
 * a1:两线段重合点
 * a2:线段2终点
 */
double angelcal(MyPoint a0, MyPoint a1, MyPoint a2)
{
    double theta = qAtan2(a0.PointX - a1.PointX, a0.PointY - a1.PointY) - qAtan2(a2.PointX - a1.PointX, a2.PointY - a1.PointY);
    if (theta > M_PI)
        theta -= 2 * M_PI;
    if (theta < -M_PI)
        theta += 2 * M_PI;

    theta = abs(theta * 180.0 / M_PI);
  
    return theta;
}

返回旋转后的坐标,坐标点绕另一坐标点逆时针旋转x度

//a0:起始点;CirCenter:圆心;angle:角度
MyPoint pointccwrotate(MyPoint a0,MyPoint CirCenter,double angle)
{
    MyPoint result;
    result.PointX = (a0.PointX - CirCenter.PointX)*qCos(angle/180*M_PI) - (a0.PointY - CirCenter.PointY)*qSin(angle/180*M_PI) + CirCenter.PointX;
    result.PointY = (a0.PointX - CirCenter.PointX)*qSin(angle/180*M_PI) + (a0.PointY - CirCenter.PointY)*qCos(angle/180*M_PI) + CirCenter.PointY;
    return result;
}

返回旋转后的坐标,坐标点绕另一坐标点顺时针旋转x度

//a0:起始点;CirCenter:圆心;angle:角度
MyPoint pointcwrotate(MyPoint a0,MyPoint CirCenter,double angle)
{
    MyPoint result;
    result.PointX = (a0.PointX - CirCenter.PointX)*qCos(angle/180*M_PI) + (a0.PointY - CirCenter.PointY)*qSin(angle/180*M_PI) + CirCenter.PointX;
    result.PointY = (a0.PointX - CirCenter.PointX)*qSin(angle/180*M_PI) + (a0.PointY - CirCenter.PointY)*qCos(angle/180*M_PI) + CirCenter.PointY;
    return result;
}

文件

//取得文件路径 
QString FilePath = QFileDialog::getOpenFileName(this,"选择","../");

QPainter

QImgae对象(大小,样式)
QPainter画家对象(关联绘图设备)
QPen|QBrush画笔画刷(关联画家对象)
setpen(),setbrush(),setStyle(),setcolor()

connect

connect(),返回值FALSE/TRUE
False:链接失败,True:链接成功
发出者必须为非空非野地址,connect成功后,在任意位置都可以接收信号,触发槽函数。
--------------------------------------------------------------------------
connect()第五个参数的作用,<链接方式>:默认\队列\直接
<默认>:如果是多线程,默认使用队列;如果是单线程,默认使用直接
<Queue>:让槽函数所在的线程和接受者一样,槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。
发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。
<Direct>:让槽函数所在线程和发送者一样,槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。
效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成崩溃。
<Qt::BlockingQueuedConnection>:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。
接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。

Lamda表达式默认使用Driect链接。
例:   connect(&Timer,&QTimer::timeout,
            [=]()
            {
                Timer.stop();
                SendData();
                bConnectOk = connect(ui->PB_Test,&QPushButton::clicked,
                                    [=]()
                                    {
                                        cout << "test";
                                    });
                cout << bConnectOk;
            });
只要True == bConnectOK后,只要PB_Test接收到clicked的信号,就可以触发对应的槽函数,不受上一层逻辑的影响(再无需timeout)。

多线程

//使用信号与槽,头文件必须包含'Q_OBJECT'宏
//QThread::currentThread() 可返回线程号
1)新建一个类,继承于QObject
2)创建使用的线程处理函数(只能有一个),定义一些信号函数(signals)
3)在主线程(ui)#include<新创建类的头文件>,申明该类对象。//继承Object的对象不能指定父对象
4) 创建子线程QThread对象//可以指定父对象
5) 将线程处理函数关联子线程(MoveToThread)
6) 开启子线程(QThread->strat()),使用信号与槽触发线程成立函数
7) 退出:QThread->quit() ;Linux<pthread_exit();>
8) 释放资源: QThread->wait,必要时可以将处理函数停下;Linux<pthread_join();>

QTcpSocket不能跨线程调用,也不能跨线程传址。
QTimer不能跨线程控制。"Timers cannot be started from another thread"

数据库

MYSQL:

QSqlDatabase:数据库对象
QSqlError:数据库错误对象
QSqlQuery:SQL语句对象
QVariantList:范式List

cout << QSqlDatabase::drivers();//可打印支持的数据库驱动
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");//添加数据库
db.setHostName("127.0.0.1");//数据库服务器ip
db.setUserName("root");//数据库用户名
db.setPassword("123456");//数据库密码
db.setDatabaseName("info");//用哪个数据库
db.open();//数据库是否成功打开

QSqlQuery query

***************************建表*****************************

//id:主键,自增
query.exec("create table student(id int primary key auto_increment, StuName varchar(255), age int, score int);");

***************************插入*****************************

query.exec("insert into student(StuName,age,score) values('mike',18,100);");

***************************删除*****************************

query.exec("delete from student where StuName = '%1'").arg(name);

***************************查询*****************************

query.exec("select * from student;");
//query.next()会到下一行
while(query.next() == true)
{
    //取出当前行,每一列列的内容,可以排序识别,也可以用字段匹配
    cout << query.value(0).toInt();
    cout << query.value(1).toString();
    cout << query.value("age").toInt();
    cout << query.value("score").toInt();
}

***************************批量处理*****************************
//odbc风格
    //1.预处理语句,'?'相当于占位符,自增主键可不赋值
    query.prepare("insert into student(StuName,age,score) values(?,?,?);");
    //2.给字段设置内容 List 3.给字段相应的值 按!顺序!绑定
    QVariantList StuNameList;
    QVariantList ageList;
    QVariantList scoreList;
    StuNameList << "aa" << "bb" << "cc";
    ageList << 11 << 22 << 33;
    scoreList << 100 << 100 << 99;
    query.addBindValue(StuNameList);
    query.addBindValue(ageList);
    query.addBindValue(scoreList);
    //执行预处理命令
    query.execBatch();

//oracle风格
    //占位符不同 变成(:+自定义名字)无需和字段一致
    query.prepare("insert into student(StuName,age,score) 		values(:StuName,:age,:score);");
    QVariantList StuNameList;
    QVariantList ageList;
    QVariantList scoreList;
    StuNameList << "dd" << "ee" << "ff";
    ageList << 11 << 22 << 33;
    scoreList << 100 << 100 << 99;
    //给字段绑定,!不局限于顺序!
    query.bindValue(":StuName",StuNameList);
    query.bindValue(":score",scoreList);
    query.bindValue(":age",ageList);

    query.execBatch();

***************************事务*****************************
    /*
     * 事务(Transaction),一般是指要做的或所做的事情。
     * 在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)
     * 事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
     */
    //本身单例,QSqlDatabase::database()实际就是操作db
    
    //开启一个事务
    QSqlDatabase::database().transaction(); 
    等价于 query.exec("START TRANSACTION");
    
	//开始事务
    QSqlDatabase::database().commit();
 	等价于query.exec("COMMIT");

	//回滚
	QSqlDatabase::database().rollback();
	等价于query.exec("ROLLBACK");
SQLITE:

	//SQLITE特性主键无法自增;主要配置区别,无需用户名密码,只需设置路径
	
	//添加本地SQLITE数据库
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    //设置
    db.setDatabaseName("../local.db");

XML

.Pro要 QT += xml
<QDomDocument>文档模型对象
<QDomProcessingInstruction>XML格式头
<QDomElement>元素

//创建元素(节点)名称
QDomElement Element = QDomDocument.createElement("str")
//创建属性名称
QDomAttr DomAttr = QDomDocument.createAttribute("str")
//设置属性内容
DomAttr.setNodeValue(Date);
//节点追加
QDomElement.append(QDomDocument)

//设置实体内容
QDomText DomText= QDomDocument.CreateText("str")
QDomElement DomElement = 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt是一种跨平台的C++开发框架,它提供了丰富的GUI组件库,使得开发者可以轻松地设计和创建各种件和界面。自定义件从一定程度上方便了程序的编写,让程序更加直观,使用得当的自定义件可以让程序增添不少精彩细节。仪表盘是一种比较常见的自定义件,它可以用来显示实时数据,例如速度,油量,温度等等。下面来简单介绍一下用Qt自定义一个仪表盘的一些步骤。 首先要构思好仪表盘的外观和功能,比如可以考虑盘的大小,采用什么颜色,显示哪些数据等等。 其次,需要用Qt中提供的基础件(如QPainter、QPoint、QRect)来构建自定义件的各个部分,包括盘表、指针、刻度等,然后为这些部分设置合适的属性(如颜色、位置、宽度等)。 接着,需要实现件的数据传递和刷新。一般情况下,会使用定时器或者事件触发来更新件显示的数据。考虑到仪表盘是一种实时显示数据的件,所以在设计数据刷新时需要保证刷新频率足够高,否则会出现卡顿、显示延迟等问题。 最后,为了方便其他的开发者使用该自定义件,可以将其打包成独立的Qt插件,或者直接将自定义件的源代码公开发布。 以上就是简单的Qt自定义件仪表盘的一些步骤,开发者可以根据自己的需求进行相应更改和优化。总之自定义件并不是一件简单的事情,但是如果能够掌握好最基本的知识,就能够创造出更加精美、实用的自定义件。 ### 回答2: Qt自定义件仪表盘可以用于需要展示数据的界面设计。通过自定义仪表盘,可以实现不同样式和功能的展示,并且能够满足不同场景下的需求。 在Qt中,仪表盘的设计可以通过绘图、圆弧、指针和动画的实现,使得界面更加直观、美观,也更加容易被用户理解和操作。可以通过Qt提供的QPainter绘图工具绘制圆弧,也可以通过QTimer制指针的动画效果。 另外,仪表盘也是可以与其他件进行绑定的。通过信号与槽的机制,可以将仪表盘的数值与其他件进行绑定,实现更加复杂的界面功能。 需要特别注意的是,仪表盘的设计需要考虑到不同屏幕分辨率的适配性。通过使用Qt提供的屏幕适配机制,可以实现不同分辨率下的仪表盘展示效果。 总之,Qt自定义件仪表盘是一个非常实用、优雅的设计元素,可以帮助开发者快速开发出漂亮的界面,并且提高用户体验。 ### 回答3: Qt是一个强大的C++跨平台框架,自带了很多常用的UI件,但是有时候我们也需要自定义一些件来满足我们的需求。今天我们来介绍一下如何使用Qt自定义一个仪表盘件。 首先我们需要继承QWidget类,命名为Dashboard。然后我们需要在Dashboard的构造函数中初始化一些常量,比如外部圆弧的宽度、内部圆弧的半径等等。接着我们需要重写paintEvent函数,绘制仪表盘的外部圆弧、刻度、指针等等,具体绘制方式可以根据需求灵活设置。 为了使仪表盘可以在Qt Designer中拖拽使用,我们需要在Dashboard类中加入QIB_DESIGNER_EXPORT_WIDGETS宏。最后在.pro文件中添加如下代码: ``` QT += designer TARGET = Dashboard TEMPLATE = lib HEADERS += Dashboard.h SOURCES += Dashboard.cpp QIB_DESIGNER_EXPORT_WIDGETS(Dashboard) ``` 这样我们就可以在Qt Designer中使用Dashboard自定义件了。当然,使用自定义件也需要相应的信号槽机制来进行交互操作。 总的来说,自定义件可以更好地满足我们的需求,同时也可以提高界面的美观度。在自定义件的过程中,我们要考虑到件的可扩展性、易用性以及代码的可维护性等方面,并在不断地改进和优化中,不断提高自己的技术水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值