| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- import sys
- sys.path.append('/home/lida/Downloads/lilypond-2.24.1/python')
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import Qt, QThread, pyqtSignal
- from PyQt5.QtGui import QPixmap
- from PyQt5 import uic
- import keyboard
- from ly import *
- from ly import transposition
- from abjad import *
- class SheetMusicEditor(QMainWindow):
- class KeyboardListener(QThread):
- note_added = pyqtSignal(str)
- def __init__(self, parent=None):
- super().__init__(parent=parent)
- self.key_to_note = {
- "c": Pitch("c'"),
- "d": Pitch("d'"),
- "e": Pitch("e'"),
- "f": Pitch("f'"),
- "g": Pitch("g'"),
- "a": Pitch("a'"),
- "b": Pitch("b'"),
- }
- def run(self):
- while True:
- key = keyboard.read_event().name
- if key in self.key_to_note:
- note = Note.from_pitch(self.key_to_note[key])
- self.note_added.emit(note.to_lilypond() + "")
- def __init__(self):
- super(SheetMusicEditor, self).__init__()
- uic.loadUi("qtdesigner_zkouska.ui", self)
- self.keyboard_listener = self.KeyboardListener()
- self.keyboard_listener.note_added.connect(self.add_note_to_file)
- self.keyboard_listener.start()
- self.show()
-
- self.pushButton.clicked.connect(self.transpose_up)
- self.pushButton_2.clicked.connect(self.transpose_down)
- self.krizek_button.clicked.connect(self.add_krizek_to_file)
- self.becko_button.clicked.connect(self.add_becko_to_file)
- self.treble_button.setChecked(True)
- self.treble_button.toggled.connect(self.clef_changed)
- self.alto_button.toggled.connect(self.clef_changed)
- self.bass_button.toggled.connect(self.clef_changed)
- #self.pushButton_3.clicked.connect(self.make_big)
- #self.pushButton_4.clicked.connect(self.make_small)
- self.save_button.clicked.connect(self.saveFile)
- self.openFile_button.clicked.connect(self.openFile)
- self.new_file_button.clicked.connect(self.create_new_file)
- self.refresh_button.clicked.connect(self.refresh_sheet)
- self.c_button.clicked.connect(lambda: self.add_note_to_file("c'"))
- self.d_button.clicked.connect(lambda: self.add_note_to_file("d'"))
- self.e_button.clicked.connect(lambda: self.add_note_to_file("e'"))
- self.f_button.clicked.connect(lambda: self.add_note_to_file("f'"))
- self.g_button.clicked.connect(lambda: self.add_note_to_file("g'"))
- self.a_button.clicked.connect(lambda: self.add_note_to_file("a'"))
- self.b_button.clicked.connect(lambda: self.add_note_to_file("b'"))
- self.lineEdit(self.change_title)
- line_edit = QLineEdit()
- line_edit.textChanged.connect(lambda text: change_title(title=text))
- #tady takové divné, ten první a třetí řádek spolu neinteragují hezky
- self.bpm_slider = QSlider(Qt.Horizontal)
- self.bpm_slider.setMinimum(1)
- self.bpm_slider.setMaximum(10000)
- self.bpm_slider.setSingleStep(5)
- self.bpm_slider.setValue(120)
- self.bpm_slider.setTickInterval(30)
- self.bpm_slider.setTickPosition(QSlider.TicksBelow)
- self.bpm_slider.valueChanged.connect(self.bpm_changed)
- self.horizontalLayout_2.addWidget(self.bpm_slider)
- self.actionClose.triggered.connect(exit)
-
- def transpose_up(self):
- self.pitch = transposition.transpose_pitch(self.pitch, "1")
- def transpose_down(self):
- self.pitch = transposition.transpose_pitch(self.pitch, "-1")
- def add_becko_to_file(self):
- # Get current text in music editor
- current_text = self.musicEdit.toPlainText()
- # Add znaminko to music editor
- new_text = current_text.rstrip() + "{ \flat }" + " "
- # Set new text in music editor
- self.musicEdit.setPlainText(new_text)
- def add_krizek_to_file(self):
- # Get current text in music editor
- current_text = self.musicEdit.toPlainText()
- # Add znaminko to music editor
- new_text = current_text.rstrip() + "{ \sharp }" + " "
- # Set new text in music editor
- self.musicEdit.setPlainText(new_text)
-
- def bpm_changed(slider_val, self):
- bpm = slider_val
- with open("test.ly", "r+") as file:
- data = file.read()
- file.seek(0)
- file.truncate()
- parameter = f"\\override Score.MetronomeMark #'stencil = ##f \\override Score.MetronomeMark #'break-visibility = ##(#f #f #f) \\tempo {bpm}"
- data = re.sub(r'\\override Score\.MetronomeMark #\'stencil = ##f \\override Score\.MetronomeMark #\'break-visibility = ##\(#f #f #f\) \\tempo \d+', parameter, data)
- file.write(data)
- def clef_changed(self):
- if self.alto_button.isChecked():
- clef = 'alto'
- elif self.bass_button.isChecked():
- clef = 'bass'
- else:
- clef = 'treble'
-
- with open("new_file.ly", "r") as f:
- code = f.read()
-
- # Replace the clef in the LilyPond code
- code = re.sub(r'\\clef\s+\w+', f'\\clef {clef}', code)
- # Write the modified LilyPond code to a new file
- with open("new_file.ly", "w") as f:
- f.write(code)
- def add_note_to_file(self, note):
- # Get current text in music editor
- current_text = self.musicEdit.toPlainText()
- # Add note to music editor
- new_text = current_text + note + " "
- # Set new text in music editor
- self.musicEdit.setPlainText(new_text)
- def create_new_file(self):
- with open("new_file.ly", "w") as f:
- f.write("\\version \"2.18.2\"\n\n")
- f.write(f'\\clef {self.clef}\n')
- f.write("\\header {\n")
- f.write("\ttitle = \"Untitled\"\n")
- f.write("}\n\n")
- f.write("\\score {\n")
- f.write("\t\\new Staff { }\n")
- f.write("\t\\layout { }\n")
- f.write("}\n")
- self.pitch = Pitch("c'")
- def change_title(self, new_title):
- new_title = self.lineEdit.text()
- with open("new_file.ly", "r") as f:
- code = f.read()
-
- # Replace the title in the LilyPond code
- code = re.sub("\ttitle = \"Untitled\"\n", f"\ttitle = \"{new_title}\"\n", code)
- # Write the modified LilyPond code to a new file
- with open("new_file.ly", "w") as f:
- f.write(code)
- def refresh_sheet(self):
- # Get current text in music editor
- current_text = self.musicEdit.toPlainText()
- # Create LilyPond file
- lilypond_file = LilyPondFile()
- lilypond_file.add_item(current_text)
- # Create PNG file
- png_filename = "sheet_music.png"
- lilypond_file.to_pdf(png_filename)
- # Load PNG file and display it in the graphics view
- pixmap = QPixmap(png_filename)
- self.graphicsView.setScene(QGraphicsScene(self))
- self.graphicsView.scene().addPixmap(pixmap)
- self.graphicsView.fitInView(self.graphicsView.scene().sceneRect(), Qt.KeepAspectRatio)
- def saveFile(self):
- # Get filename from user
- filename, _ = QFileDialog.getSaveFileName(self, "Save Sheet Music", "", "Lilypond Files (*.ly)")
- if not filename:
- return
- # Create LilyPond file
- lilypond_file = LilyPondFile()
- lilypond_file.header_title = self.titleEdit.toPlainText()
- lilypond_file.add_item(self.musicEdit.toPlainText())
- # Save LilyPond file
- lilypond_format = LilyPondFormat()
- with open(filename, 'w') as f:
- f.write(lilypond_format(lilypond_file))
- def openFile(self):
- # Get filename from user
- filename, _ = QFileDialog.getOpenFileName(self, "Open Sheet Music", "", "Lilypond Files (*.ly)")
- if not filename:
- return
- # Load LilyPond file
- with open(filename, 'r') as f:
- lilypond_text = f.read()
- # Parse LilyPond file
- lilypond_file = LilyPondFile()
- lilypond_file.parse(lilypond_text)
- # Set widget values
- self.titleEdit.setPlainText(lilypond_file.header_title)
- self.musicEdit.setPlainText(lilypond_file.items()[0].to_lilypond())
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- editor = SheetMusicEditor()
- editor.show()
- sys.exit(app.exec_())
|