今天的目标是写一个动态的彩虹灯
一开始是有思路的。只是写的过程中有太多小bug了,真的是防不胜防
我的思路是:
主界面是一个开始界面,点击开始按钮之后,有一个子界面出现,显示出彩虹灯转动的效果。
内部的执行逻辑是
创建一个名为开始的Pushbutton,在用户点击了pushbutton的时候,使用connect函数来发信号到槽当中,执行槽函数,在这个槽函数中:
为一个子窗口申请内存,使用show函数。
这样程序就进入到了这个子窗口的构造函数中,构造函数中初始化了一个存放七个颜色的Label数组,分别代表彩虹的七种颜色。然后分别初始化这七个元素,使用布局将这七个颜色放到一起,目的是可以达到七个颜色一起滚动的效果,然后在为定时器分配完内存之后就可以在槽函数中设置重复动作了,因为我当时设置的是向上滚动,事实证明这的确是最省力的hhhh,然后使用一个计数器,每次执行一次函数就自增1,然后对这个计数器模6取余,这样就可以使用数组下标对布局中的Label进行设置了.如何设置呢:使用下标首先移除布局中的对应下标,之后再执行add操作,因为往布局中添加组件,QT是默认往下添加的。所以这就不需要再指定插入到哪个位置了。
上面说的这个计数器一定得是静态的,否则就需要定义在函数外面作为一个全局函数使用。说到这个我就想起上上周电话面试的时候
面试官:全局变量在C++中是如何定义的
我:放在main函数外面就是全局变量了
面试官:嗯,还有呢?放在函数里面呢?
我:嗯?额额额,static?final?
沉默。。。
面试官:好了,C++部分我就不提问了,嗯我看一下(估计当时是在看我的简历)…好那我提问一下关于计算机网络的问题巴拉巴拉巴拉。。。。
哎,现在想起来真是尴尬的要命了。。。
对了今天做彩虹灯的主要目的就是熟悉计时器,忘记说了,我个人觉得QT里面的定时器和linux里面的定时器挺像的。
反正最后也是做出来了,我自己感觉是挺好看的。滚动的
![在这里插入图片描述](https://img-blog.csdnimg.cn/05f621cfa0f24459b6263138e0e1e54b.gif =720x300#pic_center)
忘记了计时器的槽函数是一个重复执行的函数。也因为这样,我以为槽函数就直接是一个函数,里面重复处理同一个流程,不过现在明白过来了也觉得:为什么要专门创造一个定时器,就是因为定时器槽函数的作用就是让这个槽函数在定时器的作用下自己重复执行,要不然和自己设置一个可以循环的函数有什么区别呢?
Qt中的定时器和Linux中的定时器有一些区别。
首先,Qt中的定时器是基于事件循环(Event Loop)机制实现的,而Linux中的定时器通常是基于系统调用和信号机制。在Qt中,我们可以使用定时器类QTimer来设置定时器,并将相应的事件(如定时器超时事件)添加到事件队列中等待处理。而在Linux中,我们通常使用系统调用timer_create()或setitimer()来创建定时器,或者使用信号SIGALRM来处理定时器超时事件。
其次,Qt中的定时器可以在不同的线程中使用,而Linux中的定时器通常只能在单个进程中使用。在Qt中,我们可以通过设置QObject::moveToThread()函数将某个对象移动到另一个线程中,并在该线程中启动定时器,从而实现在多个线程中同时使用定时器。而在Linux中,由于进程之间的资源隔离性,不同进程之间的定时器无法互相访问和共享。
最后,Qt中的定时器还提供了一些方便的功能,如单次定时器、重复定时器、定时器延迟启动、定时器暂停/恢复等,使得开发者可以更加灵活地控制定时器的行为。而在Linux中,需要自己手动实现这些功能,增加了开发难度和工作量。
总之,Qt中的定时器是一种高级抽象,提供了更加简单、易用、灵活的定时器机制,便于开发者编写高质量的应用程序。而Linux中的定时器则更加底层,需要开发者自己处理复杂的系统调用和信号机制,适合编写更底层的系统程序和驱动程序。
Qt中的定时器和Linux中的定时器之间也有一些相同点。其中最重要的一个相同点就是它们都可以用于处理定时事件。
定时器在计算机领域中广泛应用,例如实现延时操作、周期性任务调度、实时数据采集等。Qt中的定时器和Linux中的定时器都可以满足这些需求,具有相似的功能和表现形式。
另外,Qt中的定时器和Linux中的定时器都是基于系统底层硬件或操作系统内核提供的计时器实现的,在CPU时钟周期内部使用计数器来计量时间间隔,从而精确地计算出定时器超时事件。
总之,虽然Qt中的定时器和Linux中的定时器在实现方式和功能特性上存在差异,但它们的共同点在于都能够为程序提供高效、精确的定时服务,帮助开发者实现各种定时相关的功能和应用场景。
因为在使用子窗口的时候,我的想法是直接在主窗口中出现彩虹灯,按照想法写出来之后,看了又看的确是没问题,但是就是显示说已经有另一个布局覆盖了整个窗口了,没办法使用另外一个窗口
然后我就这个查这个问题查了一个小时,最后终于找到答案,因为我的子窗口继承的QMainWindow,但是QMainWindow这个类是默认创建了一个布局的,所以没有办法再使用子布局了。
给一个gpt的回答:
据说继承QMainWindow的一个控件会隐式创建一个布局,有可能导致之后继承这个控件的窗口无法显示是这样吗?
不完全是这样。
确实,继承自 QMainWindow 的控件(如 QMainWindow、QDialog 等)会隐式创建一个布局,并将其设置为自身的布局。这个布局被称为 central widget 布局,它对插入到其中的所有子控件进行管理,以便正确地显示它们。
但是,这并不会导致之后继承这个控件的窗口无法显示。如果您继承了 QMainWindow 或 QDialog,而子类中的窗口无法显示,那么通常有其他原因导致的,例如:
没有将子控件添加到布局中:如果您没有将子控件添加到 central widget 布局中,则子控件将不会显示。您需要使用 setCentralWidget() 函数将子控件设置为 QMainWindow 的中央窗口部件。
子控件的大小超过了父控件的大小:如果子控件的大小超过了父控件的大小,它将被裁剪,只显示可见部分。确保子控件的大小不超过父控件的大小。
子控件的属性设置不正确:如果您在创建子控件时没有正确设置其属性,例如不合适的大小策略或伸缩性质,它可能无法正确地显示。
其他布局管理问题:如果您在布局管理中存在问题,例如布局类型设置不正确或缺少必要的约束条件,它也可能导致子控件无法显示。
因此,如果您在使用 QMainWindow 或 QDialog 时遇到了问题,请仔细检查代码中是否存在上述问题,并进行相应的修正。
所以说在这种时候,如果要创建一个在这个控件中的布局就需要明确的使用centralWidget设置这个布局是吗
是的,如果您想要在 QMainWindow 或 QDialog 中创建一个子控件布局,您需要将该布局设置为 central widget 的布局。
在 QMainWindow 类中,setCentralWidget() 函数用于设置 central widget,该函数接受一个 QWidget 参数。您可以将一个包含子控件的 QWidget 作为参数传递给这个函数,从而将子控件添加到中心窗口部件中。
另外之前看有人说QT里面的信号和槽与linux里面的handler(回调函数)不相同。
但是实际上我觉得他们的本质是相同的都是在运行时如果遇到了放置在相应位置上的函数指针,那么程序流程就转换到函数指针指向的函数中,执行完之后再返回继续执行主程序。但是与handler不同的是,信号和槽机制是使用connect连接信号和槽,在connect中发出信号之后,相当于是广播给了消息队列中所有的槽函数,如果槽函数的名字或什么标志(可能是看这个槽函数的父窗口/控件)和connect相对应,那么就执行这个槽函数。主要的不同就是qt有内置的消息队列(也就是事件循环),而且这个消息队列可以开发者自己设置优先级。
这里再贴一个关于事件循环的gpt的回答:
是的,Qt内置了消息队列(Message Queue),也称为事件循环(Event Loop),用于处理应用程序接收到的各种事件,如鼠标点击、键盘输入、定时器等事件。
在Qt中,事件循环是由QCoreApplication或QApplication类的exec()函数所实现的。当运行应用程序时,Qt会自动创建一个主线程,并在主线程中启动一个事件循环,用于接收和处理事件。当应用程序接收到事件时,例如鼠标点击事件,Qt会将该事件封装成一个QEvent对象,并将其添加到事件队列中。事件循环会不断地从事件队列中取出事件,并将其分发给相应的对象处理。如果没有任何事件需要处理,事件循环会一直等待,直至有新事件加入事件队列。
通过事件循环,Qt可以方便地实现多线程程序、异步编程,以及优化应用程序的性能和响应速度等。
同时,在事件循环中,Qt还提供了一些方便的函数,如postEvent()、sendEvent()、processEvents()等,允许开发者手动向事件队列中添加事件、立即处理事件,或者强制事件循环执行一定时间的事件处理等。
总之,Qt内置的消息队列和事件循环是Qt架构的重要部分,使得Qt应用程序能够优雅地处理各种事件,保证了应用程序的稳定性和可靠性。
晚上又运行了一遍彩虹灯,发现在我电脑上运行竟然发生了频闪,我觉得可能是我自己电脑的问题
今天实在是太充实了,不过没做学校布置的大作业,哎晚上回去又要加班了