[题目一]下面是关闭特定程序的代码,其中红色部分为核心代码。
- 请在pycharm里面建立一个项目,然后在Form里放置一个按钮控件
- 双击按钮控件,在合适的部分加入下面红色的代码
- 拓展举例:进一步修改程序,给出一个列表显示正在运行的程序,让用户选择关闭哪个程序。
原题给的代码好像是C#的,因为我是用python的,所有那些代码段我就都删掉了。下面给出我的代码。(因为赶时间完成实验,所以也没有很精细,可以自己去改一下)
1.UI页面设计(使用pyqt5)
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_1.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(664, 516)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(62, 22, 531, 411))
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.listView = QtWidgets.QListView(self.widget)
self.listView.setObjectName("listView")
self.horizontalLayout.addWidget(self.listView)
self.listView_2 = QtWidgets.QListView(self.widget)
self.listView_2.setObjectName("listView_2")
self.horizontalLayout.addWidget(self.listView_2)
self.verticalLayout.addLayout(self.horizontalLayout)
self.splitter = QtWidgets.QSplitter(self.widget)
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.pushButton_2 = QtWidgets.QPushButton(self.splitter)
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton = QtWidgets.QPushButton(self.splitter)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.splitter)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 664, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton_2.setText(_translate("MainWindow", "查看进程"))
self.pushButton.setText(_translate("MainWindow", "结束进程"))
这里使用的Qt Designer设计的UI,目前用到的组件并不多,所以这种图形化界面对我完全够用了。这里设计的还有有些问题,因为之前考虑美观,所以用了两个listView,但是这两个listView没有关联起来,也就是下拉页面的时候,另一个不会动,这里我没有搞,但是也挺简单的,放上别人的博客:(5条消息) 两个listview中关联同步滚动条——pyqt5_Sk_stream的博客-CSDN博客
UI页面:
2.主函数部分
导入相关库
import sys
from ui_1 import Ui_MainWindow
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QApplication, QMainWindow,QMessageBox
import os
import psutil
这里导入了psutil这个库,因为下面要把当前运行的进程放到listview中,所以导入了相关的库。
class Exp_1(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Exp_1, self).__init__(parent)
self.setupUi(self)
self.list_name = ['进程名']
self.list_pid = ['pid']
self.pid = 0
self.name = ''
self.connecter()
self.listview_name = self.listView
self.listview_pid = self.listView_2
'''用来设置View所关联的Model,可以使用Python原生的list作为数据源Model'''
self.listmodel_name = QStringListModel()
self.listmodel_pid = QStringListModel()
初始化函数,我们定义的这个类Exp_1继承了QMainWindow和 Ui_MainWindow两个类,python允许一对多继承,而Java不允许。
我们可以看到我们定义了一个connecter()函数,这个函数是用来连接按钮的。
def connecter(self):
'''按键触发'''
self.pushButton_2.clicked.connect(self.process)
self.pushButton.clicked.connect(self.kill)
def process(self):
self.listview_name.clearSelection()
'''打印进程名和pid到listview中'''
for proc in psutil.process_iter():
try:
if(proc.as_dict(attrs=['name'])['name'] == ''):
continue
self.list_name.append(proc.as_dict(attrs=['name'])['name'])
self.list_pid.append(str(proc.as_dict(attrs=['pid'])['pid']))
except psutil.NoSuchProcess:
pass
self.listmodel_name.setStringList(self.list_name)
self.listmodel_pid.setStringList(self.list_pid)
self.listview_name.setModel(self.listmodel_name)
self.listview_pid.setModel(self.listmodel_pid)
'''鼠标点击获取进程信息,并选中进程,然后弹出消息框提示'''
self.listview_name.clicked.connect(self.onClickedListView)
self.listview_pid.clicked.connect(self.onClickedListView)
def onClickedListView(self,item):
self.pid=self.list_pid[item.row()]
self.name = self.list_name[item.row()]
QMessageBox.information(self,"QListView","您选择了:" + self.list_pid[item.row()])
def kill(self):
'''执行taskkill命令'''
os.system(f'taskkill /f /pid {self.pid}')
QMessageBox.information(self, "QListView", "您杀死了:" + self.name+"("+self.pid+")"+"进程")
self.list_name = ['进程名']
self.list_pid = ['pid']
self.process()
从上面的代码可以看出来,我们UI界面的两个按钮分别绑定了一个函数,一个是查看当前进程,一个是杀死选中进程。
查看进程中还重写了鼠标点击事件,将选择的进程号PID放到一个全局变量中,方便杀死进程的时候调用该全局变量。
os.system(f'taskkill /f /pid {self.pid}')
这一句的意思就是系统执行taskkill命令。执行格式如下:
TASKKILL [/S system [/U username [/P [password]]]]
{ [/FI filter] [/PID processid | /IM imagename] } [/F] [/T]
其中/F 代表指定要强行终止的进程 /PID process id 代表指定要终止的进程的PID,这里我们就用的这两个参数。
描述:一个或多个任务或进程结束。 可以按进程 ID 或映像名(Image)结束进程。
主函数
if __name__ == "__main__":
app = QApplication(sys.argv)
w = Exp_1()
w.show()
sys.exit(app.exec_())
这里就是把上面写的类显示出来。
下面是完整代码:
#-*-coding:gb2312-*-
import sys
from ui_1 import Ui_MainWindow
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QApplication, QMainWindow,QMessageBox
import os
import psutil
class Exp_1(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Exp_1, self).__init__(parent)
self.setupUi(self)
self.list_name = ['进程名']
self.list_pid = ['pid']
self.pid = 0
self.name = ''
self.connecter()
self.listview_name = self.listView
self.listview_pid = self.listView_2
'''用来设置View所关联的Model,可以使用Python原生的list作为数据源Model'''
self.listmodel_name = QStringListModel()
self.listmodel_pid = QStringListModel()
def connecter(self):
'''按键触发'''
self.pushButton_2.clicked.connect(self.process)
self.pushButton.clicked.connect(self.kill)
def process(self):
self.listview_name.clearSelection()
'''打印进程名和pid到listview中'''
for proc in psutil.process_iter():
try:
if(proc.as_dict(attrs=['name'])['name'] == ''):
continue
self.list_name.append(proc.as_dict(attrs=['name'])['name'])
self.list_pid.append(str(proc.as_dict(attrs=['pid'])['pid']))
except psutil.NoSuchProcess:
pass
self.listmodel_name.setStringList(self.list_name)
self.listmodel_pid.setStringList(self.list_pid)
self.listview_name.setModel(self.listmodel_name)
self.listview_pid.setModel(self.listmodel_pid)
'''鼠标点击获取进程信息,并选中进程,然后弹出消息框提示'''
self.listview_name.clicked.connect(self.onClickedListView)
self.listview_pid.clicked.connect(self.onClickedListView)
def onClickedListView(self,item):
self.pid=self.list_pid[item.row()]
self.name = self.list_name[item.row()]
QMessageBox.information(self,"QListView","您选择了:" + self.list_pid[item.row()])
def kill(self):
'''执行taskkill命令'''
os.system(f'taskkill /f /pid {self.pid}')
QMessageBox.information(self, "QListView", "您杀死了:" + self.name+"("+self.pid+")"+"进程")
self.list_name = ['进程名']
self.list_pid = ['pid']
self.process()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = Exp_1()
w.show()
sys.exit(app.exec_())