I have a QPushButton named C3:
self.C3 = QtWidgets.QPushButton(self.centralwidget)
A keyboard shortcut for this button for the key 'X' for example would be:
self.C3.setShortcut(_translate("MainWindow", "X"))
But I want to trigger the button when I press the 'C3' key on my midi keyboard, not a key from pc keyboard. I can print the value of midi input using:
if midiInput.poll():
midi_events = midiInput.read(10)
print(midi_events[0][0][1])
When I press the 'C3' key, this will print 48
which is the integer value for 'C3'.
But I don't know how to make the program to recognise the input from midi on setShortcut.
Here is my code:
from PyQt5 import QtCore, QtGui, QtWidgets
from midiutil.MidiFile import MIDIFile
from music21 import *
import pygame.midi
import pygame
import time
from pygame.locals import *
import playsound
# This will be used for the playing .wav files for the keys
from threading import Thread
# This will support us for multithreading
import atexit
if hasattr(QtCore.Qt, 'AA_EnableHighDpiScaling'):
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
if hasattr(QtCore.Qt, 'AA_UseHighDpiPixmaps'):
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
device_output = 0
device_input = 1
instrument = 1
def printMIDIDeviceList():
for i in range(pygame.midi.get_count()):
print(pygame.midi.get_device_info(i), i)
# ===================================================================================
# ===================================================================================
pygame.init()
# initize Pygame MIDI ----------------------------------------------------------
pygame.midi.init()
pygame.fastevent.init()
event_get = pygame.fastevent.get
event_post = pygame.fastevent.post
input_id = pygame.midi.get_default_input_id()
# printMIDIDeviceList()
# setez dispozitivul output --------------------------------------------------------
player = pygame.midi.Output(device_output)
# setez instrumentul
player.set_instrument(instrument)
# setez dispozitivul input
midiInput = pygame.midi.Input(device_input)
# ===================================================================================
# ===================================================================================
intervalAnt = 0
start = time.time()
# create your MIDI object
mf = MIDIFile(1) # only 1 track
track = 0 # the only track
timp = 0 # start at the beginning
mf.addTrackName(track, timp, "Sample Track")
mf.addTempo(track, timp, 66)
def whatever():
with open("output.mid", 'wb') as outf:
mf.writeFile(outf)
atexit.register(whatever)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1226, 522)
# We require a sender, that will tell us which key is pressed
self.mw = MainWindow
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.C3 = QtWidgets.QPushButton(self.centralwidget)
self.C3.setGeometry(QtCore.QRect(313, 260, 31, 161))
self.C3.setStyleSheet("#C3{\n"
"background-color: rgb(242, 242, 242);\n"
"background-color: qlineargradient(spread:pad, x1:0.960545, y1:0.0962727, x2:0.795545, y2:0.119318, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(250, 250, 250, 250));}\n"
"\n"
"\n"
"#C3:pressed{\n"
"background-color: rgb(250, 250, 250);\n"
"}\n"
"\n"
"")
# ...
# Here all the buttons are created, I skipped some of them in this example
# ...
self.D2.setText("")
self.D2.setObjectName("D2")
self.F2s = QtWidgets.QPushButton(self.centralwidget)
self.F2s.setGeometry(QtCore.QRect(210, 260, 20, 101))
self.F2s.setStyleSheet("#F2s{\n"
"background-color: rgb(0, 0, 0);\n"
"\n"
"background-color: qlineargradient(spread:pad, x1:0.784, y1:0.0175, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))\n"
"}\n"
"\n"
"#F2s:pressed{\n"
"background-color: rgb(0,0,0);\n"
"background-color: qlineargradient(spread:pad, x1:0.857955, y1:0.0170455, x2:1, y2:0, stop:0.125 rgba(0, 0, 0, 255), stop:0.977273 rgba(255, 255, 255, 255))\n"
"}")
self.F2s.setText("")
self.F2s.setObjectName("F2s")
self.C7.raise_()
self.B6.raise_()
self.A6.raise_()
self.G6.raise_()
self.F6.raise_()
self.E6.raise_()
self.D6.raise_()
self.C6.raise_()
self.B5.raise_()
self.A5.raise_()
self.G5.raise_()
self.F5.raise_()
self.E5.raise_()
self.D5.raise_()
self.C5.raise_()
self.B4.raise_()
self.A4.raise_()
self.G4.raise_()
self.F4.raise_()
self.E4.raise_()
self.D4.raise_()
self.C4.raise_()
self.B3.raise_()
self.A3.raise_()
self.G3.raise_()
self.F3.raise_()
self.E3.raise_()
self.D3.raise_()
self.C3.raise_()
self.B2.raise_()
self.A2.raise_()
self.G2.raise_()
self.F2.raise_()
self.E2.raise_()
self.D2.raise_()
self.C2.raise_()
self.G3s.raise_()
self.A3s.raise_()
self.F4s.raise_()
self.D4s.raise_()
self.C4s.raise_()
self.G4s.raise_()
self.A4s.raise_()
self.F3s.raise_()
self.D3s.raise_()
self.C3s.raise_()
self.G6s.raise_()
self.F5s.raise_()
self.F6s.raise_()
self.D6s.raise_()
self.A6s.raise_()
self.C6s.raise_()
self.A5s.raise_()
self.C5s.raise_()
self.G5s.raise_()
self.D5s.raise_()
self.A2s.raise_()
self.G2s.raise_()
self.D2s.raise_()
self.C2s.raise_()
self.F2s.raise_()
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# Here we make a dict for threads called th
self.th = {}
# Let's connect a key to the button
# Let's say C3 is a button or key of piano
# These are white keys
self.C3.clicked.connect(self.run_threads)
self.D3.clicked.connect(self.run_threads)
self.E3.clicked.connect(self.run_threads)
self.F3.clicked.connect(self.run_threads)
self.G3.clicked.connect(self.run_threads)
self.A3.clicked.connect(self.run_threads)
self.B3.clicked.connect(self.run_threads)
self.C4.clicked.connect(self.run_threads)
self.D4.clicked.connect(self.run_threads)
self.E4.clicked.connect(self.run_threads)
self.F4.clicked.connect(self.run_threads)
self.G4.clicked.connect(self.run_threads)
self.A4.clicked.connect(self.run_threads)
self.B4.clicked.connect(self.run_threads)
self.C5.clicked.connect(self.run_threads)
# These are the black keys
self.C3s.clicked.connect(self.run_threads)
self.D3s.clicked.connect(self.run_threads)
self.F3s.clicked.connect(self.run_threads)
self.G3s.clicked.connect(self.run_threads)
self.A3s.clicked.connect(self.run_threads)
self.C4s.clicked.connect(self.run_threads)
self.D4s.clicked.connect(self.run_threads)
self.F4s.clicked.connect(self.run_threads)
self.G4s.clicked.connect(self.run_threads)
self.A4s.clicked.connect(self.run_threads)
# ok so lets run it.
# To show how its working lets print the path of the sender
# Similarly lets add all the keys.
# Oh yes lets play and see if all keys are working.
# Let's make function to play sound
def play_notes(self, notePath):
playsound.playsound(notePath, False)
print(notePath)
# Let's make another function to run the threads
def run_threads(self):
self.th[self.mw.sender().objectName()] = Thread(target = self.play_notes,
args = ('Notes/'+'{}.wav'.format(self.mw.sender().objectName()),))
# So here the th dict will have a key which is the name of piano key
# The thread has a target function self.play_notes, and arguments is
# simply the path Notes/keyname.ogg
# Then we start and join the thread
self.th[self.mw.sender().objectName()].start()
self.th[self.mw.sender().objectName()].join()
# if midiInput.poll(): # Daca s-a declansat un input
# midi_events = midiInput.read(10)
# print(midi_events[0][0][1])
stop = time.time()
interval = stop - start
global intervalAnt
intervalAnt = interval
#---------------------------------------------------
# add some notes
channel = 0
volume = 100
numeNota = self.mw.sender().objectName()
if numeNota == 'C3s':
pitchs = int(pitch.Pitch('C#3').ps)
elif numeNota == 'D3s':
pitchs = int(pitch.Pitch('D#3').ps)
elif numeNota == 'F3s':
pitchs = int(pitch.Pitch('F#3').ps)
elif numeNota == 'G3s':
pitchs = int(pitch.Pitch('G#3').ps)
elif numeNota == 'A3s':
pitchs = int(pitch.Pitch('A#3').ps)
elif numeNota == 'C4s':
pitchs = int(pitch.Pitch('C#4').ps)
elif numeNota == 'D4s':
pitchs = int(pitch.Pitch('D#4').ps)
elif numeNota == 'F4s':
pitchs = int(pitch.Pitch('F#4').ps)
elif numeNota == 'G4s':
pitchs = int(pitch.Pitch('G#4').ps)
elif numeNota == 'A4s':
pitchs = int(pitch.Pitch('A#4').ps)
else:
pitchs = int(pitch.Pitch(numeNota).ps)
mf.addNote(track, channel, pitchs, interval, 2, volume)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.C3.setShortcut(_translate("MainWindow", "C"))
self.D3.setShortcut(_translate("MainWindow", "V"))
self.C3s.setShortcut(_translate("MainWindow", "F"))
self.E3.setShortcut(_translate("MainWindow", "B"))
self.A3.setShortcut(_translate("MainWindow", "Q"))
self.G3.setShortcut(_translate("MainWindow", "M"))
self.F3.setShortcut(_translate("MainWindow", "N"))
self.B3.setShortcut(_translate("MainWindow", "W"))
self.G3s.setShortcut(_translate("MainWindow", "K"))
self.F3s.setShortcut(_translate("MainWindow", "J"))
self.D3s.setShortcut(_translate("MainWindow", "G"))
self.A3s.setShortcut(_translate("MainWindow", "2"))
self.A4.setShortcut(_translate("MainWindow", "I"))
self.F4s.setShortcut(_translate("MainWindow", "7"))
self.A4s.setShortcut(_translate("MainWindow", "9"))
self.E4.setShortcut(_translate("MainWindow", "T"))
self.D4.setShortcut(_translate("MainWindow", "R"))
self.D4s.setShortcut(_translate("MainWindow", "5"))
self.B4.setShortcut(_translate("MainWindow", "O"))
self.F4.setShortcut(_translate("MainWindow", "Y"))
self.C4.setShortcut(_translate("MainWindow", "E"))
self.G4.setShortcut(_translate("MainWindow", "U"))
self.C4s.setShortcut(_translate("MainWindow", "4"))
self.G4s.setShortcut(_translate("MainWindow", "8"))
self.C5.setShortcut(_translate("MainWindow", "P"))
self.A2.setShortcut(_translate("MainWindow", "Z"))
self.A2s.setShortcut(_translate("MainWindow", "S"))
self.B2.setShortcut(_translate("MainWindow", "X"))
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_())