Я новичок в tkinter, и я закодировал счетчик cps в реальном времени, который отображает ваш текущий cps, поэтому значение cps постоянно меняется. Все, что я хочу сделать, это отобразить этот вывод в графическом интерфейсе tkinter или другой графический интерфейс вместо моего выходного окна pycharm.
Это результат, который я получаю, обратите внимание, что значение cps равно постоянно меняется.
10.4 cps
В моем коде есть эта строка кода, которая печатает cps:
print(raw_raw/sec, 'cps', end = "")
Есть ли способ заставить эту строку «печатать» в графическом интерфейсе tkinter?
Есть еще такая строчка:
print("\r", end = "")
Это заставляет количество cps оставаться в той же строке, заменяя предыдущую строку, чтобы не печатать бесконечный список значений cps.
полный код:
from pynput.mouse import Listener
import time
raw_clicks = 0
sec = 0.6
def on_click(x, y, button, pressed):
global start
listener.stop()
start = time.time()
print('')
with Listener(on_click=on_click) as listener:
listener.join()
while True:
def on_click(x, y, button, pressed):
global raw_clicks
global sec
global start
raw_clicks = raw_clicks + 1
if time.time() - start > sec:
listener.stop()
raw_raw = (raw_clicks / 2)
raw_raw = round(raw_raw/sec, 1)
print("\r", end = "")
print(raw_raw, 'cps', end = "")
raw_clicks = 0
start = time.time()
with Listener(on_click=on_click) as listener:
listener.join()
Спасибо за вашу помощь






Я сделал пример, отображающий ваш cpi в cmdline, tkinter и pyqt5.
Я упростил счетчик CPI и сделал его в классе. Извините, что полностью изменил Ваш код, но так больше подходит для работы с несколькими выходными интерфейсами. В принципе, Вы можете использовать Ваш код, но он не должен быть блокирующим.
Начнем с файла click_counter.py, он будет содержать класс ClickCounter, который является нашей серверной частью, подсчитывающей клики в определенном пользователем interval (по умолчанию 1 секунда).
from threading import Thread, Event
from typing import Callable
from pynput.mouse import Listener
class ClickCounter(Thread):
"""Click counter, counting clicks / interval"""
click_count = 0
stopped = Event()
def __init__(self, callback: Callable, interval: float = 1.0) -> None:
super().__init__()
self.interval = interval
self.callback = callback
self.listener = Listener(on_click=self.click_counter)
def run(self) -> None:
"""Start mouse click listener and timer"""
self.listener.start()
while not self.stopped.wait(self.interval):
# Call callback with click counter value, after interval expires
self.callback(self.click_count)
# Reset counter
self.click_count = 0
def click_counter(self, x: float, y: float, button: int, pressed: bool) -> None:
"""Count clicks"""
if pressed:
# Count when mouse button is pressed
self.click_count += 1
def cancel(self) -> None:
"""Cancel counter timer"""
# Stop timer
self.stopped.set()
# Stop listener
self.listener.stop()
Затем мы можем определить различные выходные интерфейсы.
Начнем с cps_cmdline.py, который отображает cps в командной строке:
import signal
from time import sleep
from click_counter import ClickCounter
def print_counter(count):
print("\r", end = "")
print(count, 'cps', end = "")
click_counter = ClickCounter(print_counter)
click_counter.start()
stopped = False
def exit_app(*args):
"""Close counter and app"""
global stopped, click_counter
click_counter.cancel()
stopped = True
# Register kill signals
signal.signal(signal.SIGINT, exit_app)
signal.signal(signal.SIGTERM, exit_app)
while not stopped:
# Just run until stopped
sleep(0.1)
Чтобы отобразить cps в tkinter, используйте код в файле cps_tkinter.py:
import tkinter as tk
from cps.click_counter import ClickCounter
class Window(tk.Frame):
def __init__(self, master=None):
"""Create label and StringVar holding its text"""
super().__init__(master)
self.master = master
self.pack(fill=tk.BOTH, expand=1)
self.cps_text = tk.StringVar(value = "0 cps")
self.cps_label = tk.Label(self, textvariable=self.cps_text)
self.cps_label.place(relx=0.5, rely=0.5, anchor='center')
def print_counter(self, count):
"""Thread safe variable set"""
self.after(0, self.cps_text.set, f"{count} cps")
if __name__ == "__main__":
root = tk.Tk()
app = Window(root)
root.wm_title("CPS counter")
root.geometry("100x100")
# Create and start counter
click_counter = ClickCounter(app.print_counter)
click_counter.start()
# Start tkinter app
root.mainloop()
# tkinter app is over, cancel click_counter
click_counter.cancel()
И последнее, но не менее важное cps_qt5.py:
import sys
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout
from cps.click_counter import ClickCounter
class Window(QWidget):
sig_print_counter = pyqtSignal(int)
def __init__(self, parent=None):
"""Create label and StringVar holding its text"""
super().__init__(parent)
self.cps_label = QLabel()
self.cps_label.setText("0 cps")
self.resize(100, 100)
layout = QHBoxLayout()
layout.setAlignment(Qt.AlignHCenter)
layout.addWidget(self.cps_label)
self.setLayout(layout)
self.sig_print_counter.connect(self.print_counter)
@pyqtSlot(int)
def print_counter(self, count):
"""Thread safe label text set"""
self.cps_label.setText(f"{count} cps")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
# Create and start counter
click_counter = ClickCounter(window.sig_print_counter.emit)
click_counter.start()
app.exec()
# Qt app is over, cancel click_counter
click_counter.cancel()
Вау, какой потрясающий ответ, у меня все сработало, спасибо за вашу самоотверженность