소스 검색

received by mail 2023-04-24

Adam Dominec 2 년 전
부모
커밋
c69b856835
2개의 변경된 파일484개의 추가작업 그리고 81개의 파일을 삭제
  1. 226 8
      main_m.py
  2. 258 73
      qtdesigner_zkouska.ui

+ 226 - 8
main_m.py

@@ -1,17 +1,235 @@
+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() + "")
 
-class qtdesigner_zkouska(QDialog):
-    
     def __init__(self):
-        super(qtdesigner_zkouska, self).__init__()
+        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)
 
-def main():
-    app = QApplication([])
-    window = qtdesigner_zkouska()
-    app.exec_()
+        # Set widget values
+        self.titleEdit.setPlainText(lilypond_file.header_title)
+        self.musicEdit.setPlainText(lilypond_file.items()[0].to_lilypond())
 
 if __name__ == '__main__':
-    main()
+    app = QApplication(sys.argv)
+    editor = SheetMusicEditor()
+    editor.show()
+    sys.exit(app.exec_())

+ 258 - 73
qtdesigner_zkouska.ui

@@ -6,133 +6,318 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>982</width>
-    <height>678</height>
+    <width>969</width>
+    <height>625</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>noticky</string>
   </property>
-  <widget class="QGraphicsView" name="graphicsView">
+  <widget class="QWidget" name="verticalLayoutWidget_2">
    <property name="geometry">
     <rect>
-     <x>440</x>
-     <y>140</y>
-     <width>521</width>
-     <height>521</height>
+     <x>870</x>
+     <y>150</y>
+     <width>82</width>
+     <height>54</height>
     </rect>
    </property>
+   <layout class="QVBoxLayout" name="verticalLayout_2">
+    <item>
+     <widget class="QPushButton" name="pushButton_3">
+      <property name="text">
+       <string>+</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="pushButton_4">
+      <property name="text">
+       <string>-</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
   </widget>
-  <widget class="QFrame" name="frame">
+  <widget class="QWidget" name="verticalLayoutWidget">
    <property name="geometry">
     <rect>
-     <x>10</x>
-     <y>140</y>
-     <width>431</width>
-     <height>521</height>
+     <x>610</x>
+     <y>0</y>
+     <width>131</width>
+     <height>98</height>
     </rect>
    </property>
-   <property name="frameShape">
-    <enum>QFrame::StyledPanel</enum>
-   </property>
-   <property name="frameShadow">
-    <enum>QFrame::Raised</enum>
-   </property>
-   <widget class="QScrollBar" name="verticalScrollBar">
-    <property name="geometry">
-     <rect>
-      <x>410</x>
-      <y>0</y>
-      <width>20</width>
-      <height>471</height>
-     </rect>
-    </property>
-    <property name="orientation">
-     <enum>Qt::Vertical</enum>
-    </property>
-   </widget>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <widget class="QLabel" name="label">
+      <property name="text">
+       <string>Clef:</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QRadioButton" name="treble_button">
+      <property name="text">
+       <string>treble (G-clef)</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QRadioButton" name="alto_button">
+      <property name="text">
+       <string>alto (C-clef)</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QRadioButton" name="bass_button">
+      <property name="text">
+       <string>bass (F-clef)</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
   </widget>
-  <widget class="QScrollBar" name="verticalScrollBar_2">
+  <widget class="QWidget" name="horizontalLayoutWidget_2">
    <property name="geometry">
     <rect>
-     <x>951</x>
-     <y>140</y>
-     <width>20</width>
-     <height>501</height>
+     <x>260</x>
+     <y>0</y>
+     <width>221</width>
+     <height>31</height>
     </rect>
    </property>
-   <property name="toolTip">
-    <string/>
-   </property>
-   <property name="accessibleName">
-    <string/>
+   <layout class="QHBoxLayout" name="horizontalLayout_2">
+    <item>
+     <widget class="QLabel" name="label_2">
+      <property name="text">
+       <string>BPM</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QSlider" name="bpm_slider">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QWidget" name="horizontalLayoutWidget_3">
+   <property name="geometry">
+    <rect>
+     <x>370</x>
+     <y>30</y>
+     <width>168</width>
+     <height>41</height>
+    </rect>
    </property>
-   <property name="orientation">
-    <enum>Qt::Vertical</enum>
+   <layout class="QHBoxLayout" name="horizontalLayout_3">
+    <item>
+     <widget class="QPushButton" name="b">
+      <property name="text">
+       <string>♭</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="krizek_button">
+      <property name="text">
+       <string>#</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QWidget" name="verticalLayoutWidget_3">
+   <property name="geometry">
+    <rect>
+     <x>750</x>
+     <y>10</y>
+     <width>170</width>
+     <height>51</height>
+    </rect>
    </property>
+   <layout class="QVBoxLayout" name="verticalLayout_3">
+    <item>
+     <widget class="QLabel" name="label_3">
+      <property name="text">
+       <string>Transposition:</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QPushButton" name="pushButton">
+        <property name="text">
+         <string>+</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pushButton_2">
+        <property name="text">
+         <string>-</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+   </layout>
   </widget>
-  <widget class="QScrollBar" name="horizontalScrollBar">
+  <widget class="QPushButton" name="new_file_button">
    <property name="geometry">
     <rect>
-     <x>440</x>
-     <y>640</y>
-     <width>531</width>
-     <height>20</height>
+     <x>0</x>
+     <y>0</y>
+     <width>61</width>
+     <height>23</height>
     </rect>
    </property>
-   <property name="orientation">
-    <enum>Qt::Horizontal</enum>
+   <property name="text">
+    <string>New file</string>
    </property>
   </widget>
-  <widget class="QWidget" name="verticalLayoutWidget_2">
+  <widget class="QWidget" name="horizontalLayoutWidget_4">
    <property name="geometry">
     <rect>
-     <x>930</x>
-     <y>170</y>
-     <width>21</width>
-     <height>41</height>
+     <x>0</x>
+     <y>70</y>
+     <width>599</width>
+     <height>25</height>
     </rect>
    </property>
-   <layout class="QVBoxLayout" name="verticalLayout_2">
+   <layout class="QHBoxLayout" name="horizontalLayout_4">
+    <property name="sizeConstraint">
+     <enum>QLayout::SetMinimumSize</enum>
+    </property>
+    <property name="leftMargin">
+     <number>2</number>
+    </property>
     <item>
-     <widget class="QPushButton" name="pushButton_3">
+     <widget class="QPushButton" name="c_button">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
       <property name="text">
-       <string>+</string>
+       <string>C</string>
       </property>
      </widget>
     </item>
     <item>
-     <widget class="QPushButton" name="pushButton_4">
+     <widget class="QPushButton" name="d_button">
       <property name="text">
-       <string>-</string>
+       <string>D</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="e_button">
+      <property name="text">
+       <string>E</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="f_button">
+      <property name="text">
+       <string>F</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="g_button">
+      <property name="text">
+       <string>G</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="a_button">
+      <property name="text">
+       <string>A</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QPushButton" name="b_button">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="text">
+       <string>B</string>
       </property>
      </widget>
     </item>
    </layout>
   </widget>
-  <widget class="QWidget" name="horizontalLayoutWidget">
+  <widget class="QPushButton" name="refresh_button">
    <property name="geometry">
     <rect>
-     <x>250</x>
-     <y>10</y>
-     <width>168</width>
-     <height>80</height>
+     <x>190</x>
+     <y>0</y>
+     <width>61</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Refresh</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="save_button">
+   <property name="geometry">
+    <rect>
+     <x>130</x>
+     <y>0</y>
+     <width>61</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Save file</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="openFile_button">
+   <property name="geometry">
+    <rect>
+     <x>60</x>
+     <y>0</y>
+     <width>71</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Open file</string>
+   </property>
+  </widget>
+  <widget class="QWidget" name="verticalLayoutWidget_4">
+   <property name="geometry">
+    <rect>
+     <x>770</x>
+     <y>60</y>
+     <width>131</width>
+     <height>51</height>
     </rect>
    </property>
-   <layout class="QHBoxLayout" name="horizontalLayout">
+   <layout class="QVBoxLayout" name="verticalLayout_4">
     <item>
-     <widget class="QPushButton" name="pushButton">
+     <widget class="QLabel" name="label_4">
       <property name="text">
-       <string>+</string>
+       <string>Title:</string>
       </property>
      </widget>
     </item>
     <item>
-     <widget class="QPushButton" name="pushButton_2">
-      <property name="text">
-       <string>-</string>
-      </property>
-     </widget>
+     <widget class="QLineEdit" name="lineEdit"/>
     </item>
    </layout>
   </widget>