我想要实现的目标:
我尝试过的:
.txt file
,在打开和退出窗口时将“running
”和“not running
”写入文件中。并从一开始就检查文件内容。例如:
启动应用程序时: 1.) 检查文件内容, 2.) 如果文件内容为“running
”,则显示警告并退出应用程序 3.) 如果文件内容为“not running
”,则写入“running
”写入文件并启动应用程序 4.) 退出时将“not running
”写入文件。我面临的问题:
这种方法感觉不是实现这一目标的正确方法。
如果文件项显示“
not running
”,应用程序将显示警告并退出。虽然我希望它显示已经在运行的实例。
当应用程序退出时,由于代码中的某些错误,文件项未更新为“
not running
”(因为由于错误而永远无法到达该部分)
有人可以帮我解决这个问题吗?
您可以使用 win32gui 模块实现类似的功能。要安装它,请输入 CMD
pip install pywin32
。现在这是代码:
from win32 import win32gui
import sys
def windowEnumerationHandler(hwnd, top_windows):
top_windows.append((hwnd, win32gui.GetWindowText(hwnd)))
top_windows = []
win32gui.EnumWindows(windowEnumerationHandler, top_windows)
for i in top_windows:
if "Program" in i[1]: #CHANGE PROGRAM TO THE NAME OF YOUR WINDOW
win32gui.ShowWindow(i[0],5)
win32gui.SetForegroundWindow(i[0])
sys.exit()
from PyQt5.QtWidgets import QApplication, QWidget
def main():
#YOUR PROGRAM GOES HERE
app = QApplication(sys.argv)
w = QWidget()
w.setGeometry(500, 500, 500, 500)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
基本上,一开始,程序会获取每个打开窗口的名称。如果窗口名称等于程序名称,则将程序置于最前面并关闭程序。如果没有,则会打开一个新程序。
此解决方案不需要您安装 win32 或任何其他模块,可与 PyQt5 包本身一起使用。
import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import QSystemSemaphore, QSharedMemory
from ui import window_ui # .py file compiled from .ui file
class LoginWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.ui = window_ui.Ui_MainWindow() # call to init ui
self.ui.setupUi(self)
def launch():
app = QtWidgets.QApplication(sys.argv) # create app instance at top, to able to show QMessageBox is required
window_id = 'pingidapplication'
shared_mem_id = 'pingidsharedmem'
semaphore = QSystemSemaphore(window_id, 1)
semaphore.acquire() # Raise the semaphore, barring other instances to work with shared memory
if sys.platform != 'win32':
# in linux / unix shared memory is not freed when the application terminates abnormally,
# so you need to get rid of the garbage
nix_fix_shared_mem = QSharedMemory(shared_mem_id)
if nix_fix_shared_mem.attach():
nix_fix_shared_mem.detach()
shared_memory = QSharedMemory(shared_mem_id)
if shared_memory.attach(): # attach a copy of the shared memory, if successful, the application is already running
is_running = True
else:
shared_memory.create(1) # allocate a shared memory block of 1 byte
is_running = False
semaphore.release()
if is_running: # if the application is already running, show the warning message
QtWidgets.QMessageBox.warning(None, 'Application already running',
'One instance of the application is already running.')
return
# normal process of creating & launching MainWindow
window = LoginWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
launch()
这个解决方案是我从最初发布在此网站上的 C++ 代码转换而来的。