Pyqt5 klavyede tuşlara basmayı algılama

Tek tuşu şu şekilde algılayabiliyorum

    def keyPressEvent(self, event:QKeyEvent):
        if event.key()==16777272:
            print("basla")
        elif event.key() == 16777273:
            print("bitir")

fakat ben programın CTRL+SHİFT+F9 da çalışmasını istiyorsam ne yapmalıyım

And işleci kullanılabilir diye düşünüyorum.

event.key() tek değer alıyor başka tuşa basınca Değeri değişyor.

Arkadaşlar bu keyPressEvent sadece uygulama öndeyken çalışıyormuş ben uygulama arka plandada olsa çalışmasını istiyorum nasıl bir yol kullanabilirim

event.key’in atadığı değerlerle bir dizi oluştur. Son üç değer ctrl+alt+del ise fonksiyonu çalıştır ardından listeyi temizle. Listeyi oluşturan ilk elemanı otomatik olarak 2 saniye arayla sil.

Onu yaparım şimdide uygulama arka plandayken çalışmasını nasıl sağlaycağım

Event.key değiştir brom

Ne kullanmalıyım bunu değiştirdim QShortcut kullanmayı denedim ama uygulama arkaplandayken çalışmıyor keyboard modülünü kullandığımda kısayola bastığım an yanıt vermiyor diyor
Edit:Soracak olursa bağladığım fonksiyonda hata yok butona bağladığımda sorunsuz çalışıyor

Şimdi işin rengi değişti.

Uygulama arka plandayken, işletim sistemi bu kısayolun hangi programa göndereceğini nasıl ayırsın?

Yani uygulamanın dışında bir yerdesin ve kısayolu kullandığında işletim sistemin çalışan hangi programa göndereceğini kendiliğinden mi ayırsın?

Anlamaya çalışıyorum.

Bu durumda üzerinde çalışılabilir bir sorun çünkü.

Edit 1:
Soru zordu galiba

Denemeden :

Skycoder42/QHotkey: A global shortcut/hotkey for Desktop Qt-Applications (github.com)

qhotkey önereyim.

Alternatiflerine bakarız.

Arasında dağ kadar sorma farkı var.

Neyse siz bakın. Takılırsanız, üzerinde çalışabiliriz, belki bir çözüm buluruz.

EDIT 2:
Verdiğim kink C dilinde, içinde bakıp, python a adapte edebilir miyim diye bakıyorum. Doğrudan kurmaya çalışmazsın umarım.

EDIT 3:

Evet bir tane işe yarar kod çıktı.

from pynput import keyboard

def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    print('{0} released'.format(
        key))
    if key == keyboard.Key.esc:
        # Stop listener
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
    on_press=on_press,
    on_release=on_release)
listener.start()

Handling the keyboard — pynput 1.7.6 documentation

Buradan bir key listener örneği. Başka bir programda dahi olsan listener, basılan tuşu yakalıyor.

Bunu kendi programına adapte edip,

Yakaladığın tuş istediğin tuş olduğunda, programını öne getirmesini kodlayabilirsin.

image

Az daha zorlarsak keylogger yazacağız ha gayret.

Kullandığı kütüphane/modül , pynput

Kurmakta zorluk çekmedim.

Kolay gelsin.

Bu kodu arayüze nasıl uygulayacağım keyboard modülü ile bunu yapabiliyordum ama arayüze uygulamaya çalıştığımda yanıt vermiyor dediydi bundada aynı şekilde yanıt vermiyor diyor küçük bir örnek verirmisiniz arayüze nasıl uygulaycağım hakkında

Kodunuzu ekler misiniz üzerinde oynayalım.

nasıl uyguladığınızı göremedim.

Diyordur doğrudur da ben nasıl yaptığınızı göremiyorum.

Tabi ki verebilirim ama sizin kodunuza göre yapmak daha doğru olmaz mı?

Çünkü ben hataları, yanıt vermiyorları vs göremiyorum.

EDIT 1:

Örneği de verelim. Hem de en basitinden.

import keyboard
from PyQt5.QtWidgets import *
import keyboard

keyboard.add_hotkey("ctrl+alt+j", lambda: print("ctrl+alt+j was pressed"))

app = QApplication([])
label = QLabel('Hello World!')
label.show()
app.exec()

Burada lamda fonksiyon yerine istediğin yada çalıştıracağın fonksiyonu yazabilirsin.

Kodu çalıştırdım başka bir yerde bile olsa tuş kombinasyonunu tıkladığımda. Konsola mesajı yazıyor.

Aynı kodu denediydim yanıt vermiyor dediydi tekrar dedi şimdide yanıt vermiyor diyor
Arayüzde doldurulması gereken kısımlar var o kısımların hepsi doldurulduysa kod çalışıyor fakat o kısımların hepsi doldurulmadıysa şu kısım devreye giriyor


ve yanıt vermiyor kısayolu araya sokmazsam butonla çalıştırsam bu kısım düzgün çalışıyor ama kısayolla çalıştırınca yanıt vermiyor diyor
Kısayolla çalıştırınca

Buton ilen çalıştırınca

Kusuruma bakma. Hiç bir şey anlamadım.

Demiştir kesin inanıyorum size de, ben göremedim. Nerede diyor?

Kısa yolu nasıl devreye sokuyorsunuz?

Buton ile çalıştırmak ve hotkey ile çağrı yapmak farklı şeyler.

Hotkey size zatece bir tuş grubuna fonksiyon sunar. Sizin onları bir event’e bağlamanız gerekir.

Ben hiç bir event’inizi göremiyorum.

Örnek açık çözüm de var lakin sizin kodunuz yok. Ben kodunuzun resimlerini değil kendilerini görmek gerekiyor.

Mesela buton clik event’iniz nerede?

hot key tuşunuza button event’ini bağlamayı deneyin. Yada hotkey in çağırdığı fonksiyon bir button event’i tetiklesin.

Olay olulturma nedir bir bakın. Bir buton tıklandı olayı oluşturan bir fonksiyon yazın, hotkey e o kodu bağlayın.

Örnek de verdim oradan yararlanmaya çalışın.

Kodunuz olmadan bu resimlerle bu kadar oluyor kusura bakmayın.

Buton böyle

self.startbutton.clicked.connect(lambda :self.startt())

Kısayol ile böyle

add_hotkey("ctrl+alt+j", lambda:self.startt())

fonksiyonların içi böyle

    def startt(self):
        if not self.yazıyormu:
            self.kontrol()
    def kontrol(self):
        if self.mesajinput.toPlainText()=="":
            self.hataver("Lütfen mesaj giriniz")
        elif self.surehesapla()==0:
            self.hataver("Lütfen süre kısmını doldurun")
        elif self.check_group.checkedButton() is None:
            self.hataver("Lütfen bir seçenek seçin")
        elif self.check2.checkState() and not self.mousepositionx:
            self.hataver("Mosenizin basacağı konumu ayarlaryın(Ctrl+K)")
        else:
            self.yazıyormu = True
            self.timer.start(int(self.surehesapla()))
    def hataver(self,sebep):
        msgBox = QMessageBox()
        msgBox.setWindowIcon(QIcon("Hydra_symbol.png"))
        msgBox.setIcon(QMessageBox.Critical)
        msgBox.setText("Hata:")
        msgBox.setInformativeText(sebep)
        msgBox.setWindowTitle("Hata")
        msgBox.setStandardButtons(QMessageBox.Ok)
        label = msgBox.findChild(QLabel, "qt_msgbox_label")
        label.setMinimumWidth(300)
        msgBox.setWindowFlags(Qt.WindowStaysOnTopHint)
        msgBox.exec_()
    def surehesapla(self):
        if not self.milisaniyeinput.text():
            self.milisaniye = 0
        else:
            self.milisaniye = int(self.milisaniyeinput.text())
        if not self.saniyeinput.text():
            self.saniye = 0
        else:
            self.saniye = int(self.saniyeinput.text())
        if not self.dakikainput.text():
            self.dakika = 0
        else:
            self.dakika = int(self.dakikainput.text())
        if not self.saatinput.text():
            self.saat = 0
        else:
            self.saat = int(self.saatinput.text())
        self.dakika += self.saat * 60
        self.saniye += self.dakika * 60
        self.milisaniye += self.saniye * 1000
        return self.milisaniye

yani ikiside aynı yere bağlanıyor ama ilki çalışınca


bu sonuç çıkıyor
ikincisi çalışınca

bu sonuç çıkıyor
buraları mı istiyordunuz tam anlamadım

Şöyle yapalım.

Ben size örnek bir kod ekliyorum.

Bu kod bir button içeriyor.

Sizin ki de hangi butona bastığınızda çalışıyorsa o butonu bağlarsınız.

import sys
import keyboard

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Window(QMainWindow):
	def __init__(self):
		super().__init__()

		self.setWindowTitle("Python ")
		self.setGeometry(100, 100, 600, 400)
		self.UiComponents()
		self.show()

	def UiComponents(self):

		button = QPushButton("CLICK", self)
		button.setGeometry(200, 150, 100, 30)
		button.clicked.connect(self.clickme)
   
	def clickme(self):

		print("pressed")

App = QApplication(sys.argv)
window = Window()
keyboard.add_hotkey("ctrl+alt+j", window.clickme)
sys.exit(App.exec())

Bu kodda clickme benim buton tanımlamam, sizde hangi butonsa onu bulun.

koduma nasıl bağladığıma bakın.

Benim örnek kodu çalıştırırsanız anlarsınız.

Bir form bir buton oluşturuyor.

Formun dışında yada içinde herhangi bir anda tuş kombinasyonuna basarsanız.

Buton fonksiyonunu çağırıyor.

Her hangi bir takılma , yanıt vermeme durumu yok.

Şablon olarak kullandığım kodu deneyebilirsiniz.

Sizin kodunuzda neden lamda var? Ben örnek olması için tek satır bir fonksiyon olarak koyduğumu belirttim.

Yukarıdaki örneğime uygun olarak yeniden kodunuzu gözden geçirir misiniz lütfen.

print(“deneme”) gibi şeylere bağlayınca yanıt vermeme gibi sorun oluşmuyor ama hata kutusu açmaya bağladığımda yanıt vermiyor sizin kod gibi düzelttim kodumu birşey değişmedi

Artık arka planda da olsa hotkey yakalayabiliyoruz. Burada bir sorun kalmadı.

Hata kutusunu açmaya nasıl bağladınız?

Bir de bu gösterdiğiniz kodun başın nerede? Bir class falan var mı?

Daha bizim kod gibi düzelttiniz mi göremedik. Görelim bir şey değişmemişse o zaman bakarız.

def startt(self):
    if not self.yazıyormu:
        self.kontrol()
def kontrol(self):
    if self.mesajinput.toPlainText()=="":
        self.hataver("Lütfen mesaj giriniz")
    elif self.surehesapla()==0:
        self.hataver("Lütfen süre kısmını doldurun")
    elif self.check_group.checkedButton() is None:
        self.hataver("Lütfen bir seçenek seçin")
    elif self.check2.checkState() and not self.mousepositionx:
        self.hataver("Mosenizin basacağı konumu ayarlaryın(Ctrl+K)")
    else:
        self.yazıyormu = True
        self.timer.start(int(self.surehesapla()))
def hataver(self,sebep):
    msgBox = QMessageBox()
    msgBox.setWindowIcon(QIcon("Hydra_symbol.png"))
    msgBox.setIcon(QMessageBox.Critical)
    msgBox.setText("Hata:")
    msgBox.setInformativeText(sebep)
    msgBox.setWindowTitle("Hata")
    msgBox.setStandardButtons(QMessageBox.Ok)
    label = msgBox.findChild(QLabel, "qt_msgbox_label")
    label.setMinimumWidth(300)
    msgBox.setWindowFlags(Qt.WindowStaysOnTopHint)
    msgBox.exec_()

Var class falan ama kod 250 satır diye atmadım

app=QApplication(argv)
windoww=window()
add_hotkey("ctrl+alt+j", windoww.startt)
exit(app.exec_())

böyle yaptım ama değişmedi

Sınıfı şundan sordum. Sizin çağırdığınız kısım öncesinde yapılması gereken bir şeyler varsa çağırdığınız kısım doğru çalışmamış olabilir.

Bir de buton olayını takip ettiğiniz, butona bastığınızda çalışan kodu görebilir miyiz?

Burada windoww.startt doğru giriş noktanız olmayabilir.

Doğru noktayı bulabilmek için sınıf yapınızı ve buton olayını nasıl işlediğinizi de görmekte fayda var.

EDIT:

Sebebi de şu:

Sizin hotkey için bir mesaj işleme kuyruğuna bağlanmanız gerekiyor.

Ve nasıl bağlayacağımız kodunuza bağlı.

Siz örnek verin ben hallederim derseniz.

from PyQt5.QtWidgets import QAction, QApplication, QMainWindow, QMenu


class KeyBoardManager(QObject):
    F1Signal = pyqtSignal()

    def start(self):
        keyboard.add_hotkey("F1", self.F1Signal.emit, suppress=True)


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__(flags=Qt.WindowStaysOnTopHint)

        self.menu = QMenu("Menu")
        self.menu.addAction(QAction("menu1", self.menu))
        self.menu.addAction(QAction("menu2", self.menu))
        self.menu.addAction(QAction("menu3", self.menu))

        manager = KeyBoardManager(self)
        manager.F1Signal.connect(self.show_menu)
        manager.start()

    def show_menu(self):
        print("111")
        self.menu.popup(QCursor.pos())
        print("222")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(False)
    win = MainWindow()
    # win.show()
    sys.exit(app.exec_())

Burada ana pencere yok. F1 Tuşuna bastığınızda;

Herhangi bir yere menü açıyor.

Menü çağrınızı işliyor.

Yani menü çağrınıza bağlamış oluyorsunuz.

printlere takılmayın, bunlar menü çağrısı içinde sizin kodunuz varsayın.

python - How to show a QMenu using global keyboard shortcut in PyQt5? - Stack Overflow

        manager = KeyBoardManager(self)
        manager.F1Signal.connect(self.show_menu)
        manager.start()

kısmı size bir bağlantı sunar.

Ama söylediğim gibi her şey sizin kodunuzun çalışma mekanizmasına bağlı.

Teşekkür ederim oldu

1 Beğeni