宁波大学 软件技术exp_2_1 (1)

这篇博客介绍了如何使用Python的PyQt5库创建一个UI界面,展示当前运行的进程,并允许用户选择结束特定进程。通过结合psutil库获取进程信息,实现了在两个列表视图中显示进程名和PID。用户点击列表中的进程,程序会记录所选PID并在需要时执行taskkill命令结束进程。
摘要由CSDN通过智能技术生成

[题目一]下面是关闭特定程序的代码,其中红色部分为核心代码。

  1. 请在pycharm里面建立一个项目,然后在Form里放置一个按钮控件
  2. 双击按钮控件,在合适的部分加入下面红色的代码
  3. 拓展举例:进一步修改程序,给出一个列表显示正在运行的程序,让用户选择关闭哪个程序。

原题给的代码好像是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_())

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CV_py

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值