鱼C论坛

 找回密码
 立即注册
查看: 8956|回复: 20

[技术交流] 温故而知新---PyQt5学习笔记系列---我就要关掉你!

[复制链接]
发表于 2015-5-20 15:03:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

1.jpg
0. 呃,学习有一段时间了,
大概学了下面这些:
窗口(QWidget),框架(QFrame),信号(Signal),槽(Slot),标签(QLabel),按钮(QPushButton),布局(Layout),托盘(QSystemTrayIcon),样式(QSS)。

当然只是了解了其中很少的一部分。
不过就算少也能做一些界面嘛, 练习练习。

1.  综合应用小栗子——关机程序。
1.0 呃,最近老是手残,明明点了关机早上发现居然还开着- -。。所以就试着写了这个小程序自己用~~。

1.1 如何实现关机?
想到了系统自带命令。
Linux没考虑,因为自己用的嘛。如果你想写个win和linux都想用的,呃,可以用。
  1. import platform
  2. platform.system()
复制代码

来判断是什么系统。

呐win下的关机命令就是
  1. shutdown /?
复制代码

查看这个信息。

  1. 没有参数   显示帮助。这与键入 /? 是一样的。
  2. /?         显示帮助。这与不键入任何选项是一样的。
  3. /i         显示图形用户界面(GUI)。
  4.            这必须是第一个选项。
  5. /l         注销。这不能与 /m 或 /d 选项一起使用。
  6. /s         关闭计算机。
  7. /r         关闭并重新启动计算机。
  8. /g         关闭并重新启动计算机。系统重新启动后,
  9.             重新启动所有注册的应用程序。
  10. /a         中止系统关闭。
  11.             这只能在超时期间使用。
  12. /p         关闭本地计算机,没有超时或警告。
  13.             可以与 /d 和 /f 选项一起使用。
  14. /h         休眠本地计算机。
  15.             可以与 /f 选项一起使用。
  16. /e         记录计算机意外关闭的原因。
  17. /m \\computer 指定目标计算机。
  18. /t xxx     设置关闭前的超时为 xxx 秒。
  19.             有效范围是 0-315360000 (10 年),默认值为 30。
  20.             如果超时时间大于 0,则默示 /f
  21.             参数。
  22. /c "comment" 重启动或关闭的原因的注释。
  23.             最多允许 512 个字符。
  24. /f         强制正在运行的应用程序关闭,不前台警告用户。
  25.             当为 /t 参数指定大于 0 的值时,
  26.             则默示 /f 参数。
  27. /d [p|u:]xx:yy  提供重新启动或关机的原因。
  28.             p 表明重新启动或关闭是计划内的。
  29.             u 表示原因由用户定义。
  30.             如果 p 和 u 均未指定,则是计划外重新启动
  31.             或关闭。
复制代码


1.2 OK,知道了命令那我们把它封装在python里呗。
我创建了一个func.py文件。
  1. import os


  2. class ShutDown:
  3.     def shutDown(self, time=0):
  4.         # 关机。
  5.         command = 'shutdown /s /t %d' % (time)
  6.         os.system(command)

  7.     def reset(self, time=0):
  8.         # 重启。
  9.         command = 'shutdown /r /t %d' % (time)
  10.         os.system(command)

  11.     def logout(self, time=0):
  12.         # 注销。
  13.         command = 'shutdown /l /t %d' % (time)
  14.         os.system(command)

  15.     def cancel(self):
  16.         # 取消。
  17.         os.system('shutdown /a')
复制代码

完全的调用命令,没啥好说的,关于直接点取消他的报错信息会在控制台显示,一般不用管,没啥用,除非你想根据报错来做一些其他的事, 这里没啥用,我就不管了。。

2.  窗口!
写好了功能,就开始画窗口吧~~。
先画了一张草图。。
0.jpg
自上而下呢,我想的大概就是这样子了。(画图细胞匮乏,那啥,轻点吐槽。。)


先导入我们可爱的模块们~。
  1. from PyQt5.QtWidgets import *
  2. from PyQt5.QtCore import *
  3. from PyQt5.QtGui import *
  4. import sys
  5. from func import ShutDown
复制代码


之后先定义一个主要的承载框架。
  1. class Main(QWidget):
  2.     """框架部分。"""
  3.     def __init__(self, parent=None):
  4.         super(Main, self).__init__(parent)
  5.         # 设置基本属性。
  6.         self.main = parent
  7.         self.setObjectName('main')
复制代码

然后为了美观一些,把自带的标题栏给去掉了,并设置了大小。
  1.         self.setWindowFlags(Qt.FramelessWindowHint)
  2.         self.resize(350,200)
复制代码

注: setWindowFlags还有很多,目前只用到这一个。其他的用到查手册吧。在QtCore.Qt下。FramelessWindowHint看意思也大概知道,无框架窗口

标题和图标想设置就设置吧,虽然最大化看不出来,但是隐藏在任务栏时的缩略图里还是会显示的,否则图标是python的logo,标题是python了。

2.1 给他加个托盘!
  1.         self.icon = QIcon('pic/poweroff.png')
  2.         self.tray = QSystemTrayIcon(self)
复制代码

定义出托盘和一个图标。图标也可以不定义。到时候直接用也行。
托盘最重要的就是菜单了,呃,提示也很重要。
  1.         self.act_menu = QMenu(self)
  2.         self.act_close = QAction(self)
  3.         self.act_show = QAction(self)
复制代码

呃,只给菜单来了一个关闭和显示的动作。

2.2 主布局。
草图中想的是自上而下,自然布局就用垂直布局了。
  1. self.mainLayout = QVBoxLayout()
复制代码

别忘了设置。
  1. self.setLayout(self.mainLayout)
复制代码


2.3 属性设置。
托盘神马的定义好了,我们开始把他们武装起来吧。
  1.     def set_trayIcon(self):
  2.         # 基本托盘设定。
  3.         self.tray.setIcon(self.icon)
  4.         self.tray.activated.connect(self.show_tray)
  5.         self.tray.setToolTip('定时关机')
  6.         # 动作设定。
  7.         self.act_close.setText('退出')
  8.         self.act_close.triggered.connect(self.tray.hide)
  9.         self.act_close.triggered.connect(self.close)
  10.         self.act_show.setText('最大化')
  11.         self.act_show.setShortcut('ctrl+w')
  12.         self.act_show.triggered.connect(self.show)
  13.         # 添加到菜单。
  14.         self.act_menu.addAction(self.act_show)
  15.         self.act_menu.addAction(self.act_close)
  16.         # 将菜单添加给托盘。
  17.         self.tray.setContextMenu(self.act_menu)
复制代码


定义了托盘的图标,给托盘激活信号连接到一个槽(函数)show_tray,之后给托盘写了一个鼠标放上去时的提示。

之后给关闭和显示动作添加的文本,触发时(就是单击或使用快捷键时,信号是triggered)的信号所连接的槽(函数)。
Q: 为什么退出连接了两个槽,退出不就是连tray一起销毁了嘛?隐藏起来干嘛呢。
A: 呃,测试的时候发现退出后,虽然销毁了,但是它(托盘)不会自动消失,要等鼠标放上去才消失,所以先把它隐藏了,在退出程序。


还给显示的动作加了一个快捷键,需要注意的是,菜单必须处于激活状态才能用快捷键。

将动作添加给菜单,把菜单扔给托盘。

下面是托盘的两个槽。
  1.     def tri_tray(self):
  2.         # 托盘相关函数。
  3.         if not self.flag:
  4.             self.tray.show()
  5.             self.tray.showMessage('Tip', "缩小到这里了呦~~。")
  6.             self.flag = True

  7.     def show_tray(self, flag):
  8.         # 托盘信号传递相关。
  9.         if flag == 2:
  10.             self.show()
复制代码

第一个槽是如果是第一次缩小,那么将托盘激活并显示提示信息。不手动隐藏托盘将会一直显示。self.flag是我自己定义的呃,我定义的self.flag = False

第二个槽是传递信号时。介绍托盘时发现activated信号无论左键右键都能单击激活,很是恼人,但是文档上写了可以有参数,不过写成activated()这样的形式会导致无法使用。因为信号不能调用嘛。。那究竟咋个传参。后来发现
  1. QSystemTrayIcon::Unknown        0        Unknown reason
  2. QSystemTrayIcon::Context        1        The context menu for the system tray entry was requested
  3. QSystemTrayIcon::DoubleClick        2        The system tray entry was double clicked
  4. QSystemTrayIcon::Trigger        3        The system tray entry was clicked
  5. QSystemTrayIcon::MiddleClick        4        The system tray entry was clicked with the middle mouse button
复制代码


双击时的值为2,所以判断是不是2就知道是不是双击触发了。

OK,主框架基本完成了,因为没有实际效果就不截图了。

---

头部。

我是自上而下写的。

  1. class Header(QFrame):
  2.     """头部"""
  3.     def __init__(self, parent=None):
  4.         super(Header, self).__init__(parent)
  5.         # 设置基本属性。
  6.         self.main = parent
  7.         self.setObjectName('header')
  8.         self.setWindowFlags(Qt.FramelessWindowHint)

  9.         # 按钮。
  10.         self.btn_exit = QPushButton(self)
  11.         self.btn_min = QPushButton(self)

  12.         # 标签。
  13.         self.lab_title = QLabel(self)

  14.         # 设置布局。
  15.         self.mainLayout = QHBoxLayout()

  16.         # 调用设置属性。
  17.         self.set_button()
  18.         self.set_label()
  19.         self.set_layout()
  20.         
  21.         # 加载样式。
  22.         with open('header.qss', 'r') as q:
  23.             self.setStyleSheet(q.read())

  24.         # 设置全局布局。
  25.         self.setLayout(self.mainLayout)
复制代码


根据草图,设置了两个按钮当最小化和关闭,一个标签当标题。
需要横着排列,那么头部的主布局就设置成水平布局了(QHBoxLayout),
当然还给头部加了个样式。

属性设置。
  1.     def set_button(self):
  2.         # 退出。
  3.         self.btn_exit.setObjectName('exit')
  4.         self.btn_exit.setText('×')
  5.         self.btn_exit.clicked.connect(self.main.tray.hide)
  6.         self.btn_exit.clicked.connect(self.main.close)
  7.         # 最小化。
  8.         self.btn_min.setObjectName('mini')
  9.         self.btn_min.setText('-')
  10.         self.btn_min.clicked.connect(self.main.hide)
  11.         self.btn_min.clicked.connect(self.main.tri_tray)
  12.    
  13.     def set_label(self):
  14.         # 标题。
  15.         self.lab_title.setObjectName('title')
  16.         self.lab_title.setText('定时关机')
复制代码


按钮设置名字,文本,连接信号。标签设置名字,文本。
需要注意的是,因为我这是另一个类,我们要把它弄成Main的子类,所以退出时退出的是的父类窗口,隐藏的也是父类的窗口。


  1.     def set_layout(self):
  2.         # 布局。
  3.         self.mainLayout.addWidget(self.lab_title)
  4.         self.mainLayout.addStretch(1)
  5.         self.mainLayout.addWidget(self.btn_min)
  6.         self.mainLayout.addWidget(self.btn_exit)
复制代码

这个布局也没啥好说的。按次序排上去就行啦。

QSS里的设置也简单。
  1. QFrame#header{
  2.     background: aqua;
  3. }

  4. QPushButton#exit, QPushButton#mini{
  5.     border: 0px solid;
  6.     color: gray;
  7.     font-weight: bold;
  8.     font-size: 15px;
  9. }

  10. QPushButton#exit:hover, QPushButton#mini:hover{
  11.     color: black;
  12. }

  13. QLabel#title{
  14.     color: black;
  15.     font-weight: 200;
  16.     font-size: 20px;
  17. }
复制代码

字面意思。不翻译了。。

写完了header我们把它添加给main。
在Main类里,你也可以重新写个专门的函数用于给Main添加新值设置布局啥的。我直接改的Main类。

Main类添加:
  1. self.header = Header(self)
复制代码

以及
  1. self.mainLayout.addWidget(self.header)
复制代码


效果:
2.jpg

因为现在只有一个所以头部占了全部的空间,先不用管,写完其他的一起规划。

---
中间(底部)。
底部的装饰没在写,只写了中间的功能区。

基本设置。
  1. class Center(QFrame):
  2.     """中间部分"""
  3.     def __init__(self, parent=None):
  4.         super(Center, self).__init__(parent)
  5.         # 设置基本属性。
  6.         self.main = parent
  7.         self.setObjectName('center')
  8.         self.setWindowFlags(Qt.FramelessWindowHint)

  9.         # 功能.
  10.         self.func = ShutDown()
复制代码

没差别,基本一样。

部件定义。
  1.         # 单选框。
  2.         self.radio_shutdown = QRadioButton(self)
  3.         self.radio_reset = QRadioButton(self)
  4.         self.radio_logout = QRadioButton(self)

  5.         # 设置时间。
  6.         self.input_hour = QSpinBox(self)
  7.         self.lab_hour = QLabel(self)
  8.         self.input_minutes = QSpinBox(self)
  9.         self.lab_minutes = QLabel(self)

  10.         # 设置按钮。
  11.         self.btn_start = QPushButton(self)
  12.         self.btn_cancel = QPushButton(self)
  13.         self.btn_exit = QPushButton(self)
复制代码

三个单选框,用于选择关机 or 重启 or 注销。
两个可上下选择的输入框,两个用于提示的label。
三个按钮,分别是启动,取消,和关闭(和x一样的功能)。

布局定义。
  1.         self.mainLayout = QVBoxLayout()
  2.         self.topLayout = QHBoxLayout()
  3.         self.centerLayout = QHBoxLayout()
  4.         self.bottomLayout = QHBoxLayout()
复制代码

根据草图呢,中间分成3个部分,上面是选项,中间是时间,下面的功能。
一个垂直布局里放着3个水平布局。


属性设置。
  1. def set_radio(self):
  2.         # 默认关机。
  3.         self.radio_shutdown.setText('关机')
  4.         self.radio_shutdown.setChecked(True)
  5.         self.radio_reset.setText('重启')
  6.         self.radio_logout.setText('注销')

  7.     def set_times(self):
  8.         # 时间设置,默认7分钟后。
  9.         self.input_hour.setValue(0)
  10.         self.input_hour.setMinimum(0)
  11.         self.input_hour.setMaximum(23)
  12.         self.input_hour.setSingleStep(1)
  13.         self.lab_hour.setText('小时')
  14.         self.input_minutes.setValue(7)
  15.         self.input_minutes.setMinimum(0)
  16.         self.input_minutes.setMaximum(60)
  17.         self.input_minutes.setSingleStep(1)
  18.         self.lab_minutes.setText('分钟')

  19.     def set_button(self):
  20.         # 设置启动和取消按钮。
  21.         self.btn_start.setObjectName('start')
  22.         self.btn_start.setText('启动')
  23.         self.btn_start.clicked.connect(self.exec_start)
  24.         self.btn_cancel.setObjectName('cancel')
  25.         self.btn_cancel.setText('取消')
  26.         self.btn_cancel.clicked.connect(self.func.cancel)
  27.         self.btn_exit.setObjectName('exit')
  28.         self.btn_exit.setText('关闭')
  29.         self.btn_exit.clicked.connect(self.main.tray.hide)
  30.         self.btn_exit.clicked.connect(self.main.close)
复制代码

单选框定义文本,默认是关机。
输入框设置初始值和范围(可以直接用setRange()来设置),设置文本和步长。标签就写俩文本。
按钮分别连接槽(函数)。

相关的槽(函数)。
  1.     def exec_start(self):
  2.         # 处理时间。
  3.         time = 3600 * int(self.input_hour.text()) + 60 * int(self.input_minutes.text())
  4.         if self.radio_shutdown.isChecked():
  5.             self.func.shutDown(time=time)
  6.         elif self.radio_reset.isChecked():
  7.             self.func.reset(time=time)
  8.         else:
  9.             self.func.logout(time-time)
复制代码

先把输入的小时和分化成秒,因为DOS命令只认识秒。
然后依次判断选中了那个,执行哪个功能,功能已经在func里面写好了。

设置布局。
  1.     def set_layout(self):
  2.         # 布局。
  3.         self.topLayout.addWidget(self.radio_shutdown)
  4.         self.topLayout.addWidget(self.radio_reset)
  5.         self.topLayout.addWidget(self.radio_logout)
  6.         self.topLayout.addStretch(1)

  7.         self.centerLayout.addWidget(self.input_hour)
  8.         self.centerLayout.addWidget(self.lab_hour)
  9.         self.centerLayout.addWidget(self.input_minutes)
  10.         self.centerLayout.addWidget(self.lab_minutes)

  11.         self.bottomLayout.addStretch(1)
  12.         self.bottomLayout.addWidget(self.btn_start)
  13.         self.bottomLayout.addWidget(self.btn_cancel)
  14.         self.bottomLayout.addWidget(self.btn_exit)

  15.         self.mainLayout.addLayout(self.topLayout)
  16.         self.mainLayout.addLayout(self.centerLayout)
  17.         self.mainLayout.addLayout(self.bottomLayout)
复制代码

依次添加,没啥好说的。

样式。
只是改变了一下颜色和加粗。。
  1. QRadioButton{
  2.     color: #880000;
  3.     font-weight: bold;
  4.     font-size: 12px;
  5. }

  6. QPushButton{
  7.     color: #5577AA;
  8.     font-weight: bold;
  9.     font-size: 12px;
  10. }
复制代码



还是要把center也添加到main里。
Main类:

  1. self.center = Center(self)
复制代码

以及
  1. self.mainLayout.addWidget(self.center)
复制代码

此时会发现很诡异,多了这么多空白。
3.jpg

稍稍修改一下Main类里面的布局。
  1.         self.mainLayout.setContentsMargins(0, 0, 0, 0)
  2.         self.mainLayout.setStretch(0, 50)
  3.         self.mainLayout.setStretch(1, 150)
复制代码

设置各个部件见的外边距。上下左右依次是0,0,0,0.。。
设置第一个和第二个部件的比例大小是50:150,也就是1:3。不用化简,直接用按照主窗口的大小,写上就行。化简神马的交给他自己处理。

效果:
4.jpg
5.jpg
6.jpg

功能效果和直接扣命令效果是一样的。

---
界面完善。
有个小问题,就是把标题栏隐藏之后,窗口就不能拖动了。
那需要重写鼠标事件来完成拖动。我在header里写的。因为main被我们覆盖掉了。
  1.     def mousePressEvent(self, event):
  2.         if event.buttons() == Qt.LeftButton:
  3.             self.position = event.globalPos() - self.main.pos()
  4.             event.accept()

  5.     def mouseMoveEvent(self, event):
  6.         if event.buttons() == Qt.LeftButton:
  7.             self.main.move(event.globalPos() - self.position)
  8.             event.accept()
复制代码


鼠标按下时的事件。
如果此时是鼠标左键。
那么将会定义一个变量self.position值为鼠标的位置-窗口位置。就是鼠标相对于窗口的差值。
7.jpg
还要在往左一直到屏幕左边。
然后当鼠标移动了。
这个时候鼠标的位置,再把之前的位置减掉。
8.jpg

然后就能拖动了。

有神马BUG要和我说呦~~。

全部代码:
  1. # 界面布局。
  2. # 无任何功能。
  3. from PyQt5.QtWidgets import *
  4. from PyQt5.QtCore import *
  5. from PyQt5.QtGui import *
  6. import sys
  7. from func import ShutDown


  8. class Main(QWidget):
  9.     """框架部分。"""
  10.     def __init__(self, parent=None):
  11.         super(Main, self).__init__(parent)
  12.         # 设置基本属性。
  13.         self.main = parent
  14.         self.setObjectName('main')
  15.         self.setWindowFlags(Qt.FramelessWindowHint)
  16.         self.resize(350,200)
  17.         # 设置系统托盘。
  18.         self.icon = QIcon('pic/poweroff.png')
  19.         self.tray = QSystemTrayIcon(self)
  20.         #    给托盘添加动作。
  21.         self.act_menu = QMenu(self)
  22.         self.act_close = QAction(self)
  23.         self.act_show = QAction(self)
  24.         #    设置提示信号。
  25.         self.flag = False

  26.         # 加载其他界面。
  27.         self.header = Header(self)
  28.         self.center = Center(self)

  29.         # 设置布局。
  30.         self.mainLayout = QVBoxLayout()

  31.         # 调用设置属性。
  32.         self.set_trayIcon()
  33.         self.set_layout()

  34.         # 设置全局布局。
  35.         self.setLayout(self.mainLayout)

  36.     def set_trayIcon(self):
  37.         # 基本托盘设定。
  38.         self.tray.setIcon(self.icon)
  39.         self.tray.activated.connect(self.show_tray)
  40.         self.tray.setToolTip('定时关机')
  41.         # 动作设定。
  42.         self.act_close.setText('退出')
  43.         self.act_close.triggered.connect(self.tray.hide)
  44.         self.act_close.triggered.connect(self.close)
  45.         self.act_show.setText('最大化')
  46.         self.act_show.setShortcut('ctrl+w')
  47.         self.act_show.triggered.connect(self.show)
  48.         # 添加到菜单。
  49.         self.act_menu.addAction(self.act_show)
  50.         self.act_menu.addAction(self.act_close)
  51.         # 将菜单添加给托盘。
  52.         self.tray.setContextMenu(self.act_menu)

  53.     def tri_tray(self):
  54.         # 托盘相关函数。
  55.         if not self.flag:
  56.             self.tray.show()
  57.             self.tray.showMessage('Tip', "缩小到这里了呦~~。")
  58.             self.flag = True

  59.     def show_tray(self, flag):
  60.         # 托盘信号传递相关。
  61.         if flag == 2:
  62.             self.show()

  63.     def set_layout(self):
  64.         # 布局。     
  65.         self.mainLayout.addWidget(self.header)
  66.         self.mainLayout.addWidget(self.center)
  67.         self.mainLayout.setContentsMargins(0, 0, 0, 0)
  68.         self.mainLayout.setStretch(0, 50)
  69.         self.mainLayout.setStretch(1, 150)


  70. class Header(QFrame):
  71.     """头部"""
  72.     def __init__(self, parent=None):
  73.         super(Header, self).__init__(parent)
  74.         # 设置基本属性。
  75.         self.main = parent
  76.         self.setObjectName('header')
  77.         self.setWindowFlags(Qt.FramelessWindowHint)

  78.         # 按钮。
  79.         self.btn_exit = QPushButton(self)
  80.         self.btn_min = QPushButton(self)

  81.         # 标签。
  82.         self.lab_title = QLabel(self)

  83.         # 设置布局。
  84.         self.mainLayout = QHBoxLayout()

  85.         # 调用设置属性。
  86.         self.set_button()
  87.         self.set_label()
  88.         self.set_layout()
  89.         
  90.         # 加载样式。
  91.         with open('header.qss', 'r') as q:
  92.             self.setStyleSheet(q.read())

  93.         # 设置全局布局。
  94.         self.setLayout(self.mainLayout)

  95.     def set_button(self):
  96.         # 退出。
  97.         self.btn_exit.setObjectName('exit')
  98.         self.btn_exit.setText('×')
  99.         self.btn_exit.clicked.connect(self.main.tray.hide)
  100.         self.btn_exit.clicked.connect(self.main.close)
  101.         # 最小化。
  102.         self.btn_min.setObjectName('mini')
  103.         self.btn_min.setText('-')
  104.         self.btn_min.clicked.connect(self.main.hide)
  105.         self.btn_min.clicked.connect(self.main.tri_tray)
  106.    
  107.     def set_label(self):
  108.         # 标题。
  109.         self.lab_title.setObjectName('title')
  110.         self.lab_title.setText('定时关机')

  111.     def set_layout(self):
  112.         # 布局。
  113.         self.mainLayout.addWidget(self.lab_title)
  114.         self.mainLayout.addStretch(1)
  115.         self.mainLayout.addWidget(self.btn_min)
  116.         self.mainLayout.addWidget(self.btn_exit)

  117.     """重写鼠标事件。"""
  118.     def mousePressEvent(self, event):
  119.         if event.buttons() == Qt.LeftButton:
  120.             self.position = event.globalPos() - self.main.pos()
  121.             event.accept()

  122.     def mouseMoveEvent(self, event):
  123.         if event.buttons() == Qt.LeftButton:
  124.             self.main.move(event.globalPos() - self.position)
  125.             event.accept()

  126. class Center(QFrame):
  127.     """中间部分"""
  128.     def __init__(self, parent=None):
  129.         super(Center, self).__init__(parent)
  130.         # 设置基本属性。
  131.         self.main = parent
  132.         self.setObjectName('center')
  133.         self.setWindowFlags(Qt.FramelessWindowHint)

  134.         # 功能.
  135.         self.func = ShutDown()

  136.         # 单选框。
  137.         self.radio_shutdown = QRadioButton(self)
  138.         self.radio_reset = QRadioButton(self)
  139.         self.radio_logout = QRadioButton(self)

  140.         # 设置时间。
  141.         self.input_hour = QSpinBox(self)
  142.         self.lab_hour = QLabel(self)
  143.         self.input_minutes = QSpinBox(self)
  144.         self.lab_minutes = QLabel(self)

  145.         # 设置按钮。
  146.         self.btn_start = QPushButton(self)
  147.         self.btn_cancel = QPushButton(self)
  148.         self.btn_exit = QPushButton(self)

  149.         # 设置布局。
  150.         self.mainLayout = QVBoxLayout()
  151.         self.topLayout = QHBoxLayout()
  152.         self.centerLayout = QHBoxLayout()
  153.         self.bottomLayout = QHBoxLayout()

  154.         # 加载属性设置。
  155.         self.set_radio()
  156.         self.set_times()
  157.         self.set_button()
  158.         self.set_layout()

  159.         # 加载样式。
  160.         with open('center.qss', 'r') as q:
  161.             self.setStyleSheet(q.read())

  162.         # 设置全局布局。
  163.         self.setLayout(self.mainLayout)

  164.     def set_radio(self):
  165.         # 默认关机。
  166.         self.radio_shutdown.setText('关机')
  167.         self.radio_shutdown.setChecked(True)
  168.         self.radio_reset.setText('重启')
  169.         self.radio_logout.setText('注销')

  170.     def set_times(self):
  171.         # 时间设置,默认7分钟后。
  172.         self.input_hour.setValue(0)
  173.         self.input_hour.setMinimum(0)
  174.         self.input_hour.setMaximum(23)
  175.         self.input_hour.setSingleStep(1)
  176.         self.lab_hour.setText('小时')
  177.         self.input_minutes.setValue(7)
  178.         self.input_minutes.setMinimum(0)
  179.         self.input_minutes.setMaximum(60)
  180.         self.input_minutes.setSingleStep(1)
  181.         self.lab_minutes.setText('分钟')

  182.     def set_button(self):
  183.         # 设置启动和取消按钮。
  184.         self.btn_start.setObjectName('start')
  185.         self.btn_start.setText('启动')
  186.         self.btn_start.clicked.connect(self.exec_start)
  187.         self.btn_cancel.setObjectName('cancel')
  188.         self.btn_cancel.setText('取消')
  189.         self.btn_cancel.clicked.connect(self.func.cancel)
  190.         self.btn_exit.setObjectName('exit')
  191.         self.btn_exit.setText('关闭')
  192.         self.btn_exit.clicked.connect(self.main.tray.hide)
  193.         self.btn_exit.clicked.connect(self.main.close)

  194.     def exec_start(self):
  195.         # 处理时间。
  196.         time = 3600 * int(self.input_hour.text()) + 60 * int(self.input_minutes.text())
  197.         if self.radio_shutdown.isChecked():
  198.             self.func.shutDown(time=time)
  199.         elif self.radio_reset.isChecked():
  200.             self.func.reset(time=time)
  201.         else:
  202.             self.func.logout(time-time)
  203.             
  204.     def set_layout(self):
  205.         # 布局。
  206.         self.topLayout.addWidget(self.radio_shutdown)
  207.         self.topLayout.addWidget(self.radio_reset)
  208.         self.topLayout.addWidget(self.radio_logout)
  209.         self.topLayout.addStretch(1)

  210.         self.centerLayout.addWidget(self.input_hour)
  211.         self.centerLayout.addWidget(self.lab_hour)
  212.         self.centerLayout.addWidget(self.input_minutes)
  213.         self.centerLayout.addWidget(self.lab_minutes)

  214.         self.bottomLayout.addStretch(1)
  215.         self.bottomLayout.addWidget(self.btn_start)
  216.         self.bottomLayout.addWidget(self.btn_cancel)
  217.         self.bottomLayout.addWidget(self.btn_exit)

  218.         self.mainLayout.addLayout(self.topLayout)
  219.         self.mainLayout.addLayout(self.centerLayout)
  220.         self.mainLayout.addLayout(self.bottomLayout)

  221. if __name__ == '__main__':
  222.     app = QApplication(sys.argv)
  223.     main = Main()
  224.     main.show()
  225.     sys.exit(app.exec_())
复制代码



评分

参与人数 5荣誉 +27 鱼币 +27 贡献 +19 收起 理由
~风介~ + 5 + 5 + 5 热爱鱼C^_^
破灬王 + 5 + 5 + 3 热爱鱼C^_^
lightninng + 2 + 2 感谢楼主无私奉献!
拈花小仙 + 5 + 5 + 3 感谢楼主无私奉献!
小甲鱼 + 10 + 10 + 8 帅爆了~

查看全部评分

本帖被以下淘专辑推荐:

  • · PyQt|主题: 45, 订阅: 73
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-5-20 16:13:09 | 显示全部楼层
光泽动人~~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-20 16:52:18 | 显示全部楼层
好厉害!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-20 18:15:13 | 显示全部楼层
厉害就要夸奖
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-21 01:16:13 | 显示全部楼层
似乎这个是主菜,我来学习一下~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-21 01:28:39 | 显示全部楼层
源码及样式文件.rar (2.97 KB, 下载次数: 29)
建议这种大的程序将原码和样式文件打包放上来,刚才我为了运行它找了半天,先看效果比较直观嘛不是~~
PS: 按钮把文字颜色一变再加个粗就是比默认的要好看啊~~
@wei_Y 为什么我@不上你~~


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-21 12:08:01 | 显示全部楼层
学习学习!!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-21 12:30:48 | 显示全部楼层
lightninng 发表于 2015-5-21 01:28
建议这种大的程序将原码和样式文件打包放上来,刚才我为了运行它找了半天,先看效果比较直观嘛不是~~
PS ...

我发现,这样也能艾特到!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-21 12:31:18 | 显示全部楼层
破灬王 发表于 2015-5-21 12:08
学习学习!!!!

多谢支持~。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-22 21:17:51 | 显示全部楼层

似乎这个是主菜,我来学习一下~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-23 11:11:37 | 显示全部楼层
:mad:需要学习的路还很长啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-23 11:26:46 | 显示全部楼层
如果加上一个付费的源码打包给土豪的话就更完美了——让鱼币更有价值~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-24 16:53:28 | 显示全部楼层

学习学习!!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-24 16:53:59 | 显示全部楼层
急用鱼币,我刷点勿怪
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-25 15:08:47 | 显示全部楼层
学习学习
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 09:55:45 | 显示全部楼层
学习学习~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 15:14:35 | 显示全部楼层
问个问题,qt相关的界面是自己写呢还是用qt设计软件来设计的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 15:28:43 | 显示全部楼层
学习学习:lol:
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 21:39:01 | 显示全部楼层
看看。。。。。。。。。。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-8-20 15:35:18 | 显示全部楼层
先收藏一下吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-22 09:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表