Cooper
Cooper

Reputation: 27

Make Pyqt Button Run Function on Mouse Down Instead of Mouse Up

I made a very simple piano roll with pyqt5. Each key is a button and runs a function to play the note sound when the button is clicked. However, the sound doesn't play until the mouse is lifted off the button. Is there a way to make it run the function as soon as the mouse hits down on the button?

here's the code:

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_())

Upvotes: 0

Views: 474

Answers (1)

musicamante
musicamante

Reputation: 48231

It is standard convention to consider a button clicked only when the mouse button is pressed and released when the cursor is over it.

If you need to call a function as soon as the button is just pressed down, use the pressed() signal:

This signal is emitted when the button is pressed down.

Do note that editing the files generated by pyuic is considered bad practice. Read the official guidelines about using Designer to know the correct ways to deal with those files (which should be only be imported).

Upvotes: 2

Related Questions