class easyInput: _display = Display(os.environ['DISPLAY']) def __init__(self): self.app = QApplication(sys.argv) self.mainWindow = QMainWindow() self.ui = Ui_mainWindow() self.ui.setupUi(self.mainWindow) self.mainWindow.setWindowTitle("方便输入") self.config_init() def config_init(self): '''与配置文件有关的初始化''' self.config = configparser.ConfigParser() self.config.read('.easy_input_rc') self.ui.lineEdit.mouseDoubleClickEvent = self.config_panel # 加载设置窗口 self.Dialog = QMainWindow() self.ui2 = Ui_config_panel() self.ui2.setupUi(self.Dialog) self.Dialog.setWindowTitle("设置") self.test_text = "我能吞下玻璃,而不伤身体" self.tmpText = "我能吞下玻璃,而不伤身体" def value_change(self): '''当设置的值改变的时候获取改变 并从新加载输入窗口设置''' self.font_size = self.ui2.font_size.value() self.windowW = self.ui2.windowW.value() self.windowH = self.ui2.windowH.value() self.windowOpacity = self.ui2.windowOpacity.value() self.font_color = self.ui2.font_color.text() self.background = self.ui2.background.text() self._lodeconfig() def save(self): ''' 点击设置中的保存键后 配置写入文件 关闭设置''' self._writeconfig() self.Dialog.close() def close(self, close_even): ''' 设置界面关闭后 恢复输入框的状态 即打开设置之前的状态''' if close_even.isAccepted() is True: # 设置输入框可操作 self.ui.lineEdit.setEnabled(True) # 恢复输入框里面的文字 self.ui.lineEdit.setText(self.tmpText) def close_back(self): '''没有保存设置恢复配置文件中的设置''' self._getconfig() self._lodeconfig() self.Dialog.close() def ch_backcolor(self): col = QColorDialog.getColor() if col.isValid(): self.ui2.background.setText(col.name()) def ch_font_color(self): col = QColorDialog.getColor() if col.isValid(): self.ui2.font_color.setText(col.name()) def config_panel(self, *kw): '''显示面板''' self.ui2.font_size.setValue(self.font_size) self.ui2.windowW.setValue(self.windowW) self.ui2.windowH.setValue(self.windowH) self.ui2.windowOpacity.setValue(self.windowOpacity) self.ui2.font_color.setText(self.font_color) self.ui2.background.setText(self.background) self.ui2.font_size.valueChanged.connect(self.value_change) self.ui2.windowW.valueChanged.connect(self.value_change) self.ui2.windowH.valueChanged.connect(self.value_change) self.ui2.windowOpacity.valueChanged.connect(self.value_change) self.ui2.font_color.textChanged.connect(self.value_change) self.ui2.background.textChanged.connect(self.value_change) self.ui2.save.clicked.connect(self.save) self.ui2.close.clicked.connect(self.close_back) self.ui2.ch_backcolor.clicked.connect(self.ch_backcolor) self.ui2.ch_font_color.clicked.connect(self.ch_font_color) self.Dialog.closeEvent = self.close self.Dialog.show() def _getconfig(self): '''获取配置文件''' self.font_size = 23 # 字体大小 self.windowW = 450 self.windowH = 60 # 窗口大小 self.windowOpacity = 0.7 # 窗口透明度 self.background = "#2F4F4F" # 背景颜色 self.font_color = "rgb(230,230,250)" # 字体颜色 if 'info' in self.config.sections(): self.font_size = int(self.config.get("info", "font_size")) self.windowW = int(self.config.get("info", "windowW")) self.windowH = int(self.config.get("info", "windowH")) self.windowOpacity = float(self.config.get("info", "windowOpacity")) self.background = self.config.get("info", "background") self.font_color = self.config.get("info", "font_color") else: self.config.add_section("info") def _writeconfig(self): '''写入配置文件''' self.config.set("info", "font_size", str(self.font_size)) self.config.set("info", "windowW", str(self.windowW)) self.config.set("info", "windowH", str(self.windowH)) self.config.set("info", "windowOpacity", str(self.windowOpacity)) self.config.set("info", "background", self.background) self.config.set("info", "font_color", self.font_color) self.config.write(open(".easy_input_rc", "w")) def _lodeconfig(self): '''根据配置文件重新设置界面''' self.mainWindow.resize(self.windowW, self.windowH) self.mainWindow.setMinimumSize(QtCore.QSize(self.windowW, self.windowH)) self.mainWindow.setMaximumSize(QtCore.QSize(self.windowW, self.windowH)) self.ui.lineEdit.setGeometry( QtCore.QRect(0, 0, self.windowW, self.windowH)) self.ui.lineEdit.setMinimumSize( QtCore.QSize(self.windowW, self.windowH)) self.ui.lineEdit.setMaximumSize( QtCore.QSize(self.windowW, self.windowH)) font = QtGui.QFont() font.setPointSize(self.font_size) self.ui.lineEdit.setFont(font) self.mainWindow.setWindowOpacity(self.windowOpacity) self.ui.lineEdit.setStyleSheet("background:{};color:{};".format( self.background, self.font_color)) self.ui2.ch_font_color.setStyleSheet("background:{}".format( self.font_color)) self.ui2.ch_backcolor.setStyleSheet("background:{};".format( self.background)) def run(self): '''运行并显示窗口''' self.mainWindow.move(*self._position()) # 输入结束信号连接run槽 self.ui.lineEdit.editingFinished.connect(self.call_action) # 重写keyPressEvent self.ui.lineEdit.keyPressEvent = self.keypressevent( self.ui.lineEdit.keyPressEvent) # 去除顶栏 和 一直在顶部 self.mainWindow.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint) self._getconfig() self._lodeconfig() self._writeconfig() self.mainWindow.show() sys.exit(self.app.exec_()) @classmethod def _position(cls): '''获取鼠标的绝对位置''' pos_info = cls._display.screen().root.query_pointer()._data return pos_info['root_x'], pos_info['root_y'] def call_action(self): ''' 输入窗口认为自己输入结束后的动作 用户按下回车 输入框失去焦点''' # 如果是因为设置界面弹出的话 if self.Dialog.isVisible(): # 设置输入框不可操作 self.ui.lineEdit.setDisabled(True) self.tmpText = self.ui.lineEdit.text() self.ui.lineEdit.setText(self.test_text) else: text = self.ui.lineEdit.text() self.write_paste(text) self.app.exit() def keypressevent(self, fun): def warr(event): if event.key() == QtCore.Qt.Key_Escape: self.call_action() else: fun(event) return warr @staticmethod def write_paste(text): pyperclip.copy(text) print("假设我已经写入到了剪切板")
class Application: def __init__(self, title, w, h): self.title = title self.w = w self.h = h self.dialList = [] self.scrollTextList = [] self.checkBoxList = [] self.app = QApplication([]) desktopSize = QDesktopWidget().availableGeometry().center() self.window = QMainWindow() self.window.setGeometry(desktopSize.x() - (self.w / 2), desktopSize.y() - (self.h / 2), self.w, self.h) self.menuBar = self.window.menuBar() self.menuBar.setNativeMenuBar(False) self.fileMenu = self.menuBar.addMenu("File") self.sampleMenu = self.menuBar.addMenu("Sample") self.exitMenu = QAction("Exit", self.window) self.fileMenu.addAction(self.exitMenu) self.exitMenu.triggered.connect(self.closeApp) self.sampleFile = QAction("Sample File", self.window) self.sampleMenu.addAction(self.sampleFile) self.sampleFile.triggered.connect(self.openFileSelector) self.generateNewSample = QAction("Generate New Sample", self.window) self.sampleMenu.addAction(self.generateNewSample) self.generateNewSample.triggered.connect(lambda: self.newSample(True)) self.pn = PyNote() self.pn.setQuantizationLevel(1 / 128) self.loadedSample = [] def closeApp(self): if self.window.isVisible(): self.window.close() def openFileSelector(self, outFile=None): fileName = QFileDialog.getOpenFileName(self.window, "Open MIDI File", "\home") if fileName[0].find(".mid") != -1: path = fileName[0] pyNoteObj = self.pn.getMidiMessages(path, quantize=True) dialogValue, pressed = QInputDialog.getInt( self.window, "Generation", "How many notes should be generated?") if pressed: if dialogValue > 0: data = self.pn.generateSequence(pyNoteObj, dialogValue, fileName=outFile) for i in self.scrollTextList: if i[0] == "SampleGeneration": text = "" for k in data: self.loadedSample.append(k) text += str(k) + "\n" textData = QLabel(self.window) textData.setText(text) textData.setGeometry( i[2].geometry().x(), i[2].geometry().y(), i[2].geometry().width(), i[2].geometry().height() * (len(data) / 12) * (100 / i[2].geometry().height())) if textData.geometry().height() < i[2].geometry( ).height(): textData.setGeometry(i[2].geometry().x(), i[2].geometry().y(), i[2].geometry().width(), i[2].geometry().height()) i[2].setWidget(textData) def newSample(self, isMod12=False): print("Loaded Sample: " + str(self.loadedSample)) vector = np.array(self.loadedSample) m = vector.shape[0] n = 1 semiToneList = [] for i in range(0, len(vector)): semiTone = self.pn.noteToSemiTone(vector[i]) semiTone2 = self.pn.noteToSemiTone(vector[i - 1]) if isMod12: diff = semiTone - semiTone2 if diff >= 12: semiTone -= 6 if diff <= -12: semiTone += 6 else: diff = semiTone - semiTone2 if diff >= 12: semiTone -= diff semiTone += random.randint(1, 11) if diff <= -12: semiTone += diff semiTone -= random.randint(1, 11) semiToneList.append(semiTone) print("Semi-Tone List: " + str(semiToneList)) ''' The next step is to add the functionality to be able to modify the actual notes to correct them based on the parameters ''' minimumNumberOfNotesPerChord = None maximumNumberOfNotesPerChord = None chordVariance = None for i in self.dialList: if i[0] == "MinChord": minimumNumberOfNotesPerChord = int(i[1].value()) if i[0] == "MaxChord": maximumNumberOfNotesPerChord = int(i[1].value()) if i[0] == "ChordVariance": chordVariance = int(i[1].value()) print(minimumNumberOfNotesPerChord, maximumNumberOfNotesPerChord, chordVariance) chordList = [] for i in semiToneList: twoChord = self.pn.noteToChord(i, 3) fiveChord = self.pn.noteToChord(i + 7, 3) oneChord = self.pn.noteToChord(i + 1, 3) chordList.append([twoChord, fiveChord, oneChord]) print(chordList) mid = MidiFile() track = MidiTrack() mid.tracks.append(track) track.append(Message('program_change', program=1, time=0)) '''track.append(Message('note_on', note = 64, velocity = 64, time = 0)) track.append(Message('note_on', note=66, velocity=64, time = 0)) track.append(Message('note_on', note=68, velocity=64, time=0)) track.append(Message('note_on', note=70, velocity=64, time=0)) track.append(Message('note_off', note=64, velocity=127, time=0)) track.append(Message('note_off', note=66, velocity=127, time=0)) track.append(Message('note_off', note=68, velocity=127, time=0)) track.append(Message('note_off', note=70, velocity=127, time= mid.ticks_per_beat))''' for chordBlock in chordList: for chord in chordBlock: for _note in chord: track.append( Message('note_on', note=_note, velocity=64, time=0)) for index, _note in enumerate(chord): if index < len(chord) - 1: track.append( Message('note_off', note=_note, velocity=127, time=0)) else: track.append( Message("note_off", note=chord[index], velocity=127, time=mid.ticks_per_beat)) mid.save('testTrack.mid') def openApplication(self): self.window.show() self.app.exec_() def addDial(self, title, x, y, w, h, labelX, minimum, maximum, key): label = QLabel(self.window) label.setText(title) label.setGeometry(labelX, y + h, w, 20) dial = QDial(self.window) dial.setGeometry(x, y, w, h) dial.setMinimum(minimum) dial.setMaximum(maximum) dial.valueChanged.connect(lambda: self.updateDial(dial)) valueLabel = QLabel(self.window) valueLabel.setText(str(dial.value())) valueLabel.setGeometry( dial.geometry().x() + int(dial.geometry().width() / 2) - 5, y - 35, w, h) self.dialList.append([key, dial, label, valueLabel]) def updateDial(self, dial): index = -1 for i in range(len(self.dialList)): if self.dialList[i][1].geometry() == dial.geometry(): index = i break if index != -1: self.dialList[index][3].setText( str(self.dialList[index][1].value())) def addScrollableText(self, data, numElements, x, y, w, h, key): textData = QLabel(self.window) textData.setText(data) textData.setGeometry(x, y, w, h * (numElements / 12) * (100 / h)) scroller = QScrollArea(self.window) scroller.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroller.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scroller.setGeometry(x, y, w, h) scroller.setWidget(textData) self.scrollTextList.append([key, textData, scroller]) def addText(self, text, x, y, w, h): label = QLabel(self.window) label.setText(text) label.setGeometry(x, y, w, h) label.show()