Qt自带的阴影类、跨线程问题汇总、hover相关、全屏轮子,一些思考。
一点思考:故事的结局重不重要?
我语文不好,但是我数学不好。
我数学不好,但是我英语不好。
我英语不好,但是我物理不好。
我物理不好,但是我化学不好。
我化学不好,但是我历史不好。
我历史不好,但是我政治不好。
我政治不好,但是我地理不好。
我地理不好,但是我生物不好。
我生物不好,但是我美术不好。
我美术不好,但是我体育不好。
此生什么都不好,来世什么都不好。
故事的结局重不重要?之前看到这个辩题,也看了那场精彩的辩论,不得不说名校出来的辩手确实能在短时间内就组织出一套完整的观点和话术来动摇对方的论点,但我觉得这道题实在出的不好。
故事的结局重要吗?诚然,如果一个绝好的故事,却以一个烂透了的结局结束,若以人生做比,一段无疾而终的恋爱,一段没有终点的旅程,一场没有屠龙的终点,一局没有boss的游戏,这些词组合在一起光是看上去就让人充满了遗憾,但即使没有终点,回头望去,一路的艰难险阻,风光正好都在向我们证明这段旅途存在。
当我看到这道辩题的时候我下意识的认为故事的结局不重要,我是一个非常在乎过程的人。我一直觉得对于我来说结局痛苦与否并不重要,因为人世间痛苦与快乐本就分不太清,我只求它货真价实。
去年的那次分手,我没有特别悲伤,那天我站在风里想了很久很久,总是不自觉地拿起手机看时间,假装会有人来给我发消息。其实我知道是不会有的,但是我不觉得痛苦,好像还是那样该吃吃该喝喝,只是感觉心里突然少了什么感情,像是突然少了一块,空落落的,并不疼。
后来我把“等有钱了一起去做”的todo list上的事自己一个人做了一遍,去看风力发电机,去看了海,去看了日出,去买了保险,去深夜的操场上裸奔...但是我都没有感觉,就好像这一切是生活里非常稀疏平常的一件事。心情非常麻木,心里并没有什么感到痛苦的地方。我觉得自己已经爱够了,该爱的都爱过了,再多就不礼貌了。
再到后来我打包把和你有关的东西准备扔掉的时候,从你给我的礼物掉出一封信。我想起在一起的那天,你双手紧抓着一封信,哭的像个小孩儿,说你很想和我在一起。那天我没有感觉,我就喝酒,喝了好多好多酒,喝到吐的时候终于哭出来了。就这么鼻涕混着眼泪昏喝了半年,我才发现原来故事的结局如此重要。
最近看了个视频,电子竞技,结局重不重要,看完真的意难平,就小森ence警亭那枪,他花了两年去反省,你说结局重要吗?
原来,一个好的结局可以感动别人,一个坏的结局只能感动自己,大抵如此吧。
一些笔记
1.qt中,自带的阴影控件使用:
上代码:
QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);
// 阴影偏移
shadowEffect->setOffset(0, 0);
// 阴影颜色;
shadowEffect->setColor(Qt::black);
// 阴影半径;
shadowEffect->setBlurRadius(15);
// 给窗口设置上当前的阴影效果;
this->ui.wid_bg->setGraphicsEffect(shadowEffect);
这段代码就是给一个窗口的周边加上阴影的,但是需要注意的一点是,这个阴影需要保证这个窗口的边上是可见的,也就是说这个窗口,也就是说这个ui.wid_bg是需要嵌套在this内的,总之要保证这个窗口的周围可见,否则这个阴影可能就会出问题。
另外需要注意的一点是,如果这个阴影只是一个单纯的分层,请不要设置这个窗口的透明度
比如这样,你就需要设置wid_bg为透明的,但是不能设置wid_cam为透明的,因为wid_cam的透明度会直接影响到阴影的深度。
2.跨线程问题相关
哎,搞了半天,又讲回跨线程问题了。讲道理我其实是比较想学着做服务器这块的,但是为什么qt这个....跨线程也太容易出问题了,而且错误了也没有相应的提示..
回到整体,跨线程有几个小问题
1.connect的第五个参数
先说在前面,就是qt的控件都是不支持跨线程调用的,所以说qt的所有跨线程调用控件实际上都是非法的(?),所以在跨线程调用控件的时候,是有可能出错的,如果两个线程同时抢一个控件,就会直接崩溃掉。
虽然说qt 的 connect函数有第五个参数 Qt::ConnectionType,但是这个默认参数我感觉是不可信的,所以需要自己设定一下,也就是在涉及跨线程调用处,都使用上信号槽机制,同时修改一下第五个参数。
跨线程调用设置参数为Qt::QueuedConnection就行,槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。一般不用Qt::BlockingQueuedConnection,这个是槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。但是这个多少容易沾点卡死了,有需要才会用。
2.互斥量mutex
在前面说了这个队列化跨线程调用的问题,虽然但是,在实际使用中又出现了另外一个问题,就是如果我现在这个节点正在被删除,但是我跨线程的函数又来操作这个节点,这种情况下要被允许运行吗?(虽然上面已经是队列化跨线程操作了,但是...哥们反正这里就是出错了,当然实际上不是这样的,具体错误要看下去)
答案肯定是否定的,这个时候这个节点不应该能够被操作,应该是要等这个节点被删除结束了,跨线程的操作才应该被允许来找节点才对,但是如果它硬要插入,这个时候就会出错了。
ok,那么问题来了,我们该怎么去做呢?这个时候就要请出我们的线程锁QMutex
这玩意用起来也简单,就是给一个指定范围的变量QMutex mutex,然后在函数开头mutex.lock(),然后mutex.unlock(),当这个mutex在lock的时候,mutex.lock()这条命令会直接阻塞整个线程
看不懂算了,回去看下操作系统,哥们真不会不懂吧都。
当然qt给定了一个更简单的用法,就是QMutexLocker,就是在函数最开始明明一个局部变量QMutexLocker am(&mutex),这个am会在当前区块被销毁的时候自动释放mutex,就不用自己去慢慢搞了,很麻烦
3.一些旧的类型转换
当然了,你在.h文件里就要把所有的int,bool类型都给初始化了最好,给它个值,或者怎么样,不然可能会出现一些意想不到的问题,比如取到随机的值,这非常操蛋,从之前的麦克风图标问题就老师出现了,到现在还导致好几次崩溃...还有就是老的规范可能允许int直接当bool类型来用,这点也要注意,编译器不会报错,但是你不应该这么写。
4.最重量级的问题:关于结构体,注意每一个warning
这个是真的重量级,因为我今天写代码的时候发现用户在退出的时候会报错,然后报错的位置是一个从列表中找到某一个特定节点的函数,只考虑到了部分情况,而有一些情况没有考虑到!也就是说有时候可能会返回一个混乱的结构体对象出来,里面的东西有,但全是乱的,你没法使用,就会在实际运用中导致一些随机的bug,这是非常恶心的,因为你也不知道bug是怎么产生的,但它就是发生了,看debug 看dmp文件也看不出,因为这个错误并不常规。
最后戴工看了一眼,发现原来是getCamare函数里有可能没返回,这个地方其实在warning里早就提示过了,所以老话说得好啊,warning不是病,坏起来真要命哦。真不知道为什么编译器会让这种问题代码通过编译。事实上还有其他可能,之后我有时间慢慢排查吧,总之这个崩溃问题暂时没有出现了。
3.hover相关
hover有几种方法实现,我稍微浅谈一下
1.qss实现
也就是在qss上的伪状态,这个是最基础的,这个就不细说了。
优点:
这个方法有点就是简单易操作,直接在qss里写好随写随用,非常方便,而且可靠性有保证,没有什么复杂的操作。
缺点:
不够灵活,使用过程中不好去该styleSheet,一般都是在使用前就写好了,而且不能hover触发一些事件
总结:只适合用于设置一些控件的状态,比如按钮的hover,如果更复杂一点的事情就做不了了
注:以下两个方法都需要setMouseTracking(true) 和 setAttribute(WA_Hover)的加持。
2.enterEvent(QEvent *event)
重写这个enterEvent方法,可以让鼠标移动到 (this) 里面的时候检测到 hover事件,并根据需要执行事件
优点:方便,随写随用,是基类函数,可靠,耐操的不二之选
缺点:这个方法是针对当前cpp文件代表的控件全局的,不能细化到某个指定窗口或者控件,具体情况具体分析。
总结:在某些控件内部使用,或者只能针对整个窗口的enterEvent,如果还需要细化,则此方法不适用。
需要设置this->setMouseTracking(true)和 this->setAttribute(WA_Hover,true);
3.eventFilter(QObject *obj,QEvent *event)
这个更是重量级,基本上对控件的任何事件都可以通过eventFilter来截取,但是这个用起来就麻烦很多
优点:精准,优雅,深入
缺点:臃肿的调用方式,不靠谱的性能,拉跨的可靠性
总结:没办法的时候用,比如一定需要hover到某个特定的窗口或者控件
需要从指定窗口到所有的父窗口全部设置setMouseTracking(true),需要设置this->setAttribute(WA_Hover,true)
需要对指定控件设置 ui.widght->installeventFilter(this)
eventFilter 代码实例如下:
bool Mengban::eventFilter(QObject * obj, QEvent * event)
{
if (obj == ui.btn_mini) {
if (event->type() == QEvent::MouseButtonPress) {
on_btn_mini_clicked();
}
}
if (obj == ui.btn_close) {
if (event->type() == QEvent::KeyPress) {
return true;
}
}
return false;
}
总之就是优点臃肿,不是很好用,麻烦,但是很没办法的时候只能用这个。
不设置setAttribute(WA_Hover,true)的话,光 setMouseTracking不一定好使
4.全屏轮子
全屏的问题我想了以下,我之前写了几个轮子,不同需求不同想法,我这里写了篇博客,参考文章如下:
三套无边框窗体的方案:可按比例拖拽窗体大小的无边框窗口和几个常见的无边框实例
Qt自带的阴影类、跨线程问题汇总、hover相关、全屏轮子,一些思考。的更多相关文章
- winform跨线程问题(有参数和无参数)
1.invoke是同步线程 using System; using System.Collections.Generic; using System.ComponentModel; using Sys ...
- JNI加载Native Library 以及 跨线程和Qt通信
Part1 Java Native Interface-JNI-JAVA本地调用 JNI标准是Java平台的一部分, 允许Java代码和其他语言进行交互; 开始实现-> Step 1) 编写Ja ...
- Qt跨线程调用错误解析及解决办法
错误提示:Error: Cannot create children for a parent that is in a different thread. 错误案例分析 新建SerialLink子线 ...
- [WinForm]WinForm跨线程UI操作常用控件类大全
前言 在C#开发的WinForm窗体程序开发的时候,经常会使用多线程处理一些比较耗时之类的操作.不过会有一个问题:就是涉及到跨线程操作UI元素. 相信才开始接触的人一定会遇上这个问题. 为了解决这个问 ...
- c#跨线程访问控件帮助类
1.背景 对于winform程序来说,当我们点击按钮,需要消耗一定时长才能拿到数据后才能显示在界面上某个控件上的情况,我们通常会专门开一个线程去拿数据,这样不会造成界面处于假死状态 2.常规做法 // ...
- c#基础,单线程,跨线程访问和线程带参数
using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms; ...
- 关于Qt跨线程调用IO子类的理解
一.疑问 突然想到,类似于QTcpsocket和QSerialport这类对象,如果是在A线程中new的,那就不能在其他线程中访问.我一般是这样做的: 封装一个QObject子类,放这些对象进去,然后 ...
- MFC、Qt、C#跨线程调用对象
MFC.Qt.C#都是面向对象的编程库 1.MFC不允许跨线程调用对象,即线程只能调用它本身分配了空间的对象 In a multi-threaded application written using ...
- ASP.NET Boilerplate 学习 AspNet Core2 浏览器缓存使用 c#基础,单线程,跨线程访问和线程带参数 wpf 禁用启用webbroswer右键菜单 EF Core 2.0使用MsSql/MySql实现DB First和Code First ASP.NET Core部署到Windows IIS QRCode.js:使用 JavaScript 生成
ASP.NET Boilerplate 学习 1.在http://www.aspnetboilerplate.com/Templates 网站下载ABP模版 2.解压后打开解决方案,解决方案目录: ...
- 在.Net中进行跨线程的控件操作(上篇:Control.Invoke)
本文的重点在于介绍如何在多线程编程中,从非UI线程上访问界面中的控件.有过多线程编程经验的人都知道,当我们在非UI线程上试图给一个界面中的控件赋值的时候,比如说label的Text属性,系统会抛出一个 ...
随机推荐
- mac 批量修改文件的后缀名
1-将需要修改的文件拖到同一个文件夹 2-打开终端输入 for i in *; do mv "$i" "$i.jpg";done
- Notebook交互式完成目标检测任务
摘要:本文将介绍一种在Notebook中进行算法开发的新方式,新手也能够快速训练自己的模型. 目标检测是计算机视觉中非常常用且基础的任务,但是由于目标检测任务的复杂性,往往令新手望而却步.本文将介绍一 ...
- PTA 1126 Eulerian Path
无向连通图,输出每个顶点的度并判断Eulerian.Semi-Eulerian和Non-Eulerian这3种情况,我们直接记录每个点所连接的点,这样直接得到它的度,然后利用深度优先和visit数组来 ...
- LinkedBlockingQueue详解
LinkedBlockingQueue介绍 [1]LinkedBlockingQueue是一个基于链表实现的阻塞队列,默认情况下,该阻塞队列的大小为Integer.MAX_VALUE,由于这个数值特别 ...
- Stanford CoreNLP无法生成实例对象
在服务器上运行Stanford,今日无法启动"StanfordCoreNLP"了,就是运行下面代码一直在运行,不结束,不报错. from stanfordcorenlp impor ...
- Codeforces Round #816 (Div. 2)/CodeForces1715
CodeForces1715 Crossmarket 解析: 题目大意 有一个 \(n \times m\) 的空间,Stanley 需要从左上角到右下角:Megan 则需要从左下角到右上角.两人可以 ...
- windows和虚拟机上的Ubuntu互传文件
1.简介 本文讲述的是通过ssh登录虚拟机上的Ubuntu系统,实现互传文件 2.Ubuntu端 2.1.安装ssh sudo apt-get update sudo apt-get install ...
- Linux---配置新服务器的常见操作(CentOS7)
修改 Centos7为字符界面 Centos7取消了之前的 inittab文件的作用,改用命令实现, systemctl get-default : 获得默认启动方式 systemctl set-de ...
- FHQ Treap 详解
鲜花 一些鲜花放在前面,平衡树学了很久,但是每学一遍都忘,原因就在于我只能 70% 理解 + 30% 背板子,所以每次都忘.这次我采取了截然不同的策略,自己按照自己的理解打一遍,大获成功(?),大概打 ...
- 机器学习中in-domine, out-domine的区别
in-domine 为域内数据,即为训练模型时使用的数据: out-domine 为域外数据,即为检验模型时使用的数据.