使 Pyqt 按钮在鼠标按下而不是鼠标按下时运行功能

Posted

技术标签:

【中文标题】使 Pyqt 按钮在鼠标按下而不是鼠标按下时运行功能【英文标题】:Make Pyqt Button Run Function on Mouse Down Instead of Mouse Up 【发布时间】:2020-12-28 05:26:53 【问题描述】:

我用pyqt5做了一个非常简单的钢琴卷。每个键都是一个按钮,并运行一个功能以在单击按钮时播放音符声音。但是,直到鼠标离开按钮时才会播放声音。有没有办法让它在鼠标按下按钮时立即运行该功能?

代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from pydub import Audiosegment
from pydub.playback import play
import threading

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(450, 210)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.c1 = QtWidgets.QPushButton(self.centralwidget)
        self.c1.setGeometry(QtCore.QRect(0, 70, 31, 111))
        self.c1.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.c1.setText("")
        self.c1.setObjectName("c1")
        self.d1 = QtWidgets.QPushButton(self.centralwidget)
        self.d1.setGeometry(QtCore.QRect(30, 70, 31, 111))
        self.d1.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.d1.setText("")
        self.d1.setObjectName("d1")
        self.e1 = QtWidgets.QPushButton(self.centralwidget)
        self.e1.setGeometry(QtCore.QRect(60, 70, 31, 111))
        self.e1.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.e1.setText("")
        self.e1.setObjectName("e1")
        self.f1 = QtWidgets.QPushButton(self.centralwidget)
        self.f1.setGeometry(QtCore.QRect(90, 70, 31, 111))
        self.f1.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.f1.setText("")
        self.f1.setObjectName("f1")
        self.g1 = QtWidgets.QPushButton(self.centralwidget)
        self.g1.setGeometry(QtCore.QRect(120, 70, 31, 111))
        self.g1.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.g1.setText("")
        self.g1.setObjectName("g1")
        self.a1 = QtWidgets.QPushButton(self.centralwidget)
        self.a1.setGeometry(QtCore.QRect(150, 70, 31, 111))
        self.a1.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.a1.setText("")
        self.a1.setObjectName("a1")
        self.b1 = QtWidgets.QPushButton(self.centralwidget)
        self.b1.setGeometry(QtCore.QRect(180, 70, 31, 111))
        self.b1.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.b1.setText("")
        self.b1.setObjectName("b1")
        self.c2 = QtWidgets.QPushButton(self.centralwidget)
        self.c2.setGeometry(QtCore.QRect(210, 70, 31, 111))
        self.c2.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.c2.setText("")
        self.c2.setObjectName("c2")
        self.d2 = QtWidgets.QPushButton(self.centralwidget)
        self.d2.setGeometry(QtCore.QRect(240, 70, 31, 111))
        self.d2.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.d2.setText("")
        self.d2.setObjectName("d2")
        self.e2 = QtWidgets.QPushButton(self.centralwidget)
        self.e2.setGeometry(QtCore.QRect(270, 70, 31, 111))
        self.e2.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.e2.setText("")
        self.e2.setObjectName("e2")
        self.f2 = QtWidgets.QPushButton(self.centralwidget)
        self.f2.setGeometry(QtCore.QRect(300, 70, 31, 111))
        self.f2.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.f2.setText("")
        self.f2.setObjectName("f2")
        self.g2 = QtWidgets.QPushButton(self.centralwidget)
        self.g2.setGeometry(QtCore.QRect(330, 70, 31, 111))
        self.g2.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.g2.setText("")
        self.g2.setObjectName("g2")
        self.a2 = QtWidgets.QPushButton(self.centralwidget)
        self.a2.setGeometry(QtCore.QRect(360, 70, 31, 111))
        self.a2.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.a2.setText("")
        self.a2.setObjectName("a2")
        self.b2 = QtWidgets.QPushButton(self.centralwidget)
        self.b2.setGeometry(QtCore.QRect(390, 70, 31, 111))
        self.b2.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.b2.setText("")
        self.b2.setObjectName("b2")
        self.c3 = QtWidgets.QPushButton(self.centralwidget)
        self.c3.setGeometry(QtCore.QRect(420, 70, 31, 111))
        self.c3.setStyleSheet("QPushButton\n"
"background-color: rgb(255, 255, 255);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.c3.setText("")
        self.c3.setObjectName("c3")
        self.c1sharp = QtWidgets.QPushButton(self.centralwidget)
        self.c1sharp.setGeometry(QtCore.QRect(20, 70, 21, 61))
        self.c1sharp.setAutoFillBackground(False)
        self.c1sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.c1sharp.setText("")
        self.c1sharp.setFlat(False)
        self.c1sharp.setObjectName("c1sharp")
        self.d1sharp = QtWidgets.QPushButton(self.centralwidget)
        self.d1sharp.setGeometry(QtCore.QRect(50, 70, 21, 61))
        self.d1sharp.setAutoFillBackground(False)
        self.d1sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.d1sharp.setText("")
        self.d1sharp.setFlat(False)
        self.d1sharp.setObjectName("d1sharp")
        self.f1sharp = QtWidgets.QPushButton(self.centralwidget)
        self.f1sharp.setGeometry(QtCore.QRect(110, 70, 21, 61))
        self.f1sharp.setAutoFillBackground(False)
        self.f1sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.f1sharp.setText("")
        self.f1sharp.setFlat(False)
        self.f1sharp.setObjectName("f1sharp")
        self.g1sharp = QtWidgets.QPushButton(self.centralwidget)
        self.g1sharp.setGeometry(QtCore.QRect(140, 70, 21, 61))
        self.g1sharp.setAutoFillBackground(False)
        self.g1sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.g1sharp.setText("")
        self.g1sharp.setFlat(False)
        self.g1sharp.setObjectName("g1sharp")
        self.a1sharp = QtWidgets.QPushButton(self.centralwidget)
        self.a1sharp.setGeometry(QtCore.QRect(170, 70, 21, 61))
        self.a1sharp.setAutoFillBackground(False)
        self.a1sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.a1sharp.setText("")
        self.a1sharp.setFlat(False)
        self.a1sharp.setObjectName("a1sharp")
        self.c2sharp = QtWidgets.QPushButton(self.centralwidget)
        self.c2sharp.setGeometry(QtCore.QRect(230, 70, 21, 61))
        self.c2sharp.setAutoFillBackground(False)
        self.c2sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.c2sharp.setText("")
        self.c2sharp.setFlat(False)
        self.c2sharp.setObjectName("c2sharp")
        self.d2sharp = QtWidgets.QPushButton(self.centralwidget)
        self.d2sharp.setGeometry(QtCore.QRect(260, 70, 21, 61))
        self.d2sharp.setAutoFillBackground(False)
        self.d2sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.d2sharp.setText("")
        self.d2sharp.setFlat(False)
        self.d2sharp.setObjectName("d2sharp")
        self.f2sharp = QtWidgets.QPushButton(self.centralwidget)
        self.f2sharp.setGeometry(QtCore.QRect(320, 70, 21, 61))
        self.f2sharp.setAutoFillBackground(False)
        self.f2sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.f2sharp.setText("")
        self.f2sharp.setFlat(False)
        self.f2sharp.setObjectName("f2sharp")
        self.g2sharp = QtWidgets.QPushButton(self.centralwidget)
        self.g2sharp.setGeometry(QtCore.QRect(350, 70, 21, 61))
        self.g2sharp.setAutoFillBackground(False)
        self.g2sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.g2sharp.setText("")
        self.g2sharp.setFlat(False)
        self.g2sharp.setObjectName("g2sharp")
        self.a2sharp = QtWidgets.QPushButton(self.centralwidget)
        self.a2sharp.setGeometry(QtCore.QRect(380, 70, 21, 61))
        self.a2sharp.setAutoFillBackground(False)
        self.a2sharp.setStyleSheet("QPushButton\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"QPushButton::pressed\n"
"background-color: rgb(255, 142, 28);\n"
"")
        self.a2sharp.setText("")
        self.a2sharp.setFlat(False)
        self.a2sharp.setObjectName("a2sharp")
        self.browsebtn = QtWidgets.QPushButton(self.centralwidget)
        self.browsebtn.setGeometry(QtCore.QRect(0, 0, 93, 28))
        self.browsebtn.setObjectName("browsebtn")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(0, 30, 451, 16))
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        
        self.chosenfilepath = ''

        self.c1.clicked.connect(self.playc1)

        self.c1sharp.clicked.connect(self.playc1sharp)

        self.d1.clicked.connect(self.playd1)
        self.d1sharp.clicked.connect(self.playd1sharp)
        self.e1.clicked.connect(self.playe1)

        self.f1.clicked.connect(self.playf1)
        self.f1sharp.clicked.connect(self.playf1sharp)
        self.g1.clicked.connect(self.playg1)
        self.g1sharp.clicked.connect(self.playg1sharp)
        self.a1.clicked.connect(self.playa1)
        self.a1sharp.clicked.connect(self.playa1sharp)
        self.b1.clicked.connect(self.playb1)
        self.c2.clicked.connect(self.playc2)
        self.c2sharp.clicked.connect(self.playc2sharp)



        self.d2.clicked.connect(self.playd2)
        self.d2sharp.clicked.connect(self.playd2sharp)
        self.e2.clicked.connect(self.playe2)

        self.f2.clicked.connect(self.playf2)
        self.f2sharp.clicked.connect(self.playf2sharp)
        self.g2.clicked.connect(self.playg2)
        self.g2sharp.clicked.connect(self.playg2sharp)
        self.a2.clicked.connect(self.playa2)
        self.a2sharp.clicked.connect(self.playa2sharp)
        self.b2.clicked.connect(self.playb2)
        self.c3.clicked.connect(self.playc3)
        
        self.browsebtn.clicked.connect(self.browsewavfiles)
        


        #key presses


    def browsewavfiles(self):
        

        self.chosenfilepath = str(QFileDialog.getOpenFileName(None,"QFileDialog.getOpenFileName()", "","Wav files (*.wav)"))

        self.chosenfilepath = self.chosenfilepath.replace("('", "")
        self.chosenfilepath = self.chosenfilepath.replace("', 'Wav files (*.wav)')", "")
        self.chosenfilepath = self.chosenfilepath.replace("\\", "/")

        for i in range(len(self.chosenfilepath)):
            if self.chosenfilepath[-i] == '/':
                self.chosenfilepath1 = self.chosenfilepath[-i+1:]
                break
            
        self.label.setText(self.chosenfilepath1)
        print(self.chosenfilepath)
        
    def playc1(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0]))
        self.t.start()

    def playc1sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.08333]))
        self.t.start()

    def playd1(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.166666]))
        self.t.start()

    def playd1sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.25]))
        self.t.start()

    def playe1(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.3333333]))
        self.t.start()

    def playf1(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.416666666]))
        self.t.start()

    def playf1sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.5]))
        self.t.start()
    def playg1(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.58333333333]))
        self.t.start()

    def playg1sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.6666666666]))
        self.t.start()
    def playa1(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.75]))
        self.t.start()
    def playa1sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.83333333]))
        self.t.start()

    def playb1(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 0.916666666]))
        self.t.start()


    def playc2(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1]))
        self.t.start()
        
    def playc2sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.083333333]))
        self.t.start()
    def playd2(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.166666]))
        self.t.start()

    def playd2sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.25]))
        self.t.start()

    def playe2(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.3333333]))
        self.t.start()

    def playf2(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.416666666]))
        self.t.start()

    def playf2sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.5]))
        self.t.start()
    def playg2(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.58333333333]))
        self.t.start()

    def playg2sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.6666666666]))
        self.t.start()
    def playa2(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.75]))
        self.t.start()
    def playa2sharp(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.83333333]))
        self.t.start()

    def playb2(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 1.916666666]))
        self.t.start()


    def playc3(self):
        self.t = threading.Thread(target=self.playnote, name='playNote', args=([self.chosenfilepath, 2]))
        self.t.start()
        
    
        


    
    def playnote(self, soundpath, octaves):
        try:
            sound = AudioSegment.from_file(soundpath, format="wav")


            new_sample_rate = int(sound.frame_rate * (2.0 ** octaves))

            hipitch_sound = sound._spawn(sound.raw_data, overrides='frame_rate': new_sample_rate)

          
            hipitch_sound = hipitch_sound.set_frame_rate(44100)

            
            play(hipitch_sound)
        except:
            print('browse for an audio file')
        
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.browsebtn.setText(_translate("MainWindow", "Browse"))
        self.label.setText(_translate("MainWindow", "none"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

标准约定是仅在按下鼠标按钮时才考虑单击按钮在光标悬停时释放按钮。

如果您需要在按下按钮后立即调用函数,请使用pressed() 信号:

按下按钮时发出此信号。

请注意,编辑 pyuic 生成的文件被认为是不好的做法。阅读有关using Designer 的官方指南,了解处理这些文件的正确方法(只能导入)。

【讨论】:

以上是关于使 Pyqt 按钮在鼠标按下而不是鼠标按下时运行功能的主要内容,如果未能解决你的问题,请参考以下文章

为啥键/鼠标侦听器检测到鼠标按下而不是按键? (Java awt 窗口)

Twitter Bootstrap 工具提示:鼠标按下时闪烁

鼠标按下时是不是可以更改可拖动元素的 z-Index?

当鼠标仍然按下时,如何防止在 Winforms Listview 中立即触发 MouseUp 事件?

如何在鼠标按下时重复调用一个函数?

在 PyQt5 中按下时如何切换按钮文本