J'ai eu ce petit code mcve:Comment remplacer correctement certaines correspondances sur un widget QScintilla?
import sys
import re
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtCore import Qt
from PyQt5.Qsci import QsciScintilla
from PyQt5 import Qsci
class FloatSlider(QtWidgets.QWidget):
value_changed = QtCore.pyqtSignal(float)
def __init__(self, value=0.0, parent=None):
super().__init__(parent)
self.slider = QtWidgets.QSlider(Qt.Horizontal)
self.label = QtWidgets.QLabel()
self.label.setAlignment(Qt.AlignCenter)
self.adjust(value)
layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.slider)
layout.addWidget(self.label)
self.slider.valueChanged.connect(self.on_value_changed)
self.setLayout(layout)
self.setWindowTitle("Adjust number")
def adjust(self, value):
width = 100 # TODO: Adjust it properly depending on input value
self.slider.setRange(value - width, value + width)
self.slider.setSingleStep(1)
self.slider.setValue(value)
self.label.setText(str(float(value)))
def on_value_changed(self, value):
# vmax, vmin = self.slider.minimum(), self.slider.maximum()
# value = 2 * value/(vmax - vmin)
self.label.setText(str(float(value)))
self.value_changed.emit(value)
class SimpleEditor(QsciScintilla):
def __init__(self, language=None, parent=None):
super().__init__(parent)
self.slider = FloatSlider(value=0.0)
self.slider.value_changed.connect(self.float_value_changed)
font = QtGui.QFont()
font.setFamily('Courier')
font.setFixedPitch(True)
font.setPointSize(10)
self.setFont(font)
self.setMarginsFont(font)
fontmetrics = QtGui.QFontMetrics(font)
self.setMarginsFont(font)
self.setMarginWidth(0, fontmetrics.width("00000") + 6)
self.setMarginLineNumbers(0, True)
self.setMarginsBackgroundColor(QtGui.QColor("#cccccc"))
self.setBraceMatching(QsciScintilla.SloppyBraceMatch)
self.setCaretLineVisible(True)
self.setCaretLineBackgroundColor(QtGui.QColor("#E8E8FF"))
if language:
self.lexer = getattr(Qsci, 'QsciLexer' + language)()
self.setLexer(self.lexer)
self.SendScintilla(QsciScintilla.SCI_FOLDALL, True)
self.setAutoCompletionThreshold(1)
self.setAutoCompletionSource(QsciScintilla.AcsAPIs)
self.setFolding(QsciScintilla.BoxedTreeFoldStyle)
# Signals/Slots
self.cursorPositionChanged.connect(self.on_cursor_position_changed)
self.copyAvailable.connect(self.on_copy_available)
self.indicatorClicked.connect(self.on_indicator_clicked)
self.indicatorReleased.connect(self.on_indicator_released)
self.linesChanged.connect(self.on_lines_changed)
self.marginClicked.connect(self.on_margin_clicked)
self.modificationAttempted.connect(self.on_modification_attempted)
self.modificationChanged.connect(self.on_modification_changed)
self.selectionChanged.connect(self.on_selection_changed)
self.textChanged.connect(self.on_text_changed)
self.userListActivated.connect(self.on_user_list_activated)
def float_value_changed(self, v):
print(v)
def on_cursor_position_changed(self, line, index):
text = self.text(line)
for match in re.finditer('(?:^|(?<=\W))\d+(?:\.\d+)?(?=$|\W)', text):
start, end = match.span()
if start <= index <= end:
pos = self.positionFromLineIndex(line, start)
x = self.SendScintilla(
QsciScintilla.SCI_POINTXFROMPOSITION, 0, pos)
y = self.SendScintilla(
QsciScintilla.SCI_POINTYFROMPOSITION, 0, pos)
point = self.mapToGlobal(QtCore.QPoint(x, y))
num = float(match.group())
message = 'number: %s' % num
self.slider.setWindowTitle('line: {0}'.format(line))
self.slider.adjust(num)
self.slider.move(point + QtCore.QPoint(0, 20))
self.slider.show()
break
def on_copy_available(self, yes):
print('-' * 80)
print("on_copy_available")
def on_indicator_clicked(self, line, index, state):
print("on_indicator_clicked")
def on_indicator_released(self, line, index, state):
print("on_indicator_released")
def on_lines_changed(self):
print("on_lines_changed")
def on_margin_clicked(self, margin, line, state):
print("on_margin_clicked")
def on_modification_attempted(self):
print("on_modification_attempted")
def on_modification_changed(self):
print("on_modification_changed")
def on_selection_changed(self):
print("on_selection_changed")
def on_text_changed(self):
print("on_text_changed")
def on_user_list_activated(self, id, text):
print("on_user_list_activated")
def show_requirements():
print(sys.version)
print(QtCore.QT_VERSION_STR)
print(QtCore.PYQT_VERSION_STR)
if __name__ == "__main__":
show_requirements()
app = QtWidgets.QApplication(sys.argv)
ex = QtWidgets.QWidget()
hlayout = QtWidgets.QHBoxLayout()
ed = SimpleEditor("JavaScript")
hlayout.addWidget(ed)
ed.setText("""#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
void main(void) {
vec2 st = (gl_FragCoord.xy/resolution.xy);
vec2 lefbot = step(vec2(0.1), st);
float pct = lefbot.x*lefbot.y;
vec2 rigtop = step(vec2(0.1), 1.-st);
pct *= rigtop.x*rigtop.y;
vec3 color = vec3(pct);
gl_FragColor = vec4(color, 1.0);""")
ex.setLayout(hlayout)
ex.show()
ex.resize(800, 600)
sys.exit(app.exec_())
Il y a plusieurs questions que je ne sais pas comment répondre:
- Mon widget curseur change la largeur widget à chaque fois que je change les valeurs, je essayé
addStrecht(1)
mais cela n'a pas fonctionné comme je l'ai prévu car il y avait trop d'espace vide entre les widgets (ie: layout arrangement -> slider | strecht | label) - Une fois que je tape une valeur numérique sur le widget QScintilla le widget FloatSlider va apparaître et c'est certainement quelque chose que je ne fais pas vouloir. Je voudrais qu'il n'apparaisse que lorsque j'appuie sur une telle valeur numérique avec le bouton gauche de la souris ou toute autre combinaison (ie: ctrl + left_mouse)
- Je ne sais pas comment remplacer correctement le texte QScintilla (regex match) sur temps réél. Idéalement, seul le texte correspondant à QScintilla devrait être modifié, par exemple, je ne veux pas remplacer tout le texte parce que l'effet visuel serait assez effrayant.
Il n'a pas eu l'impression d'ouvrir 3 questions différentes pour ces petites Les doutes étaient corrects alors j'ai décidé de les rassembler dans le même fil. Espérons que ce soit OK
Le fait que vous appelez ces "petits doutes" me porte à penser que vous sous-estimez massivement la complexité de cette tâche. Sur le deuxième point - vous voulez vraiment ** que ** le curseur reste visible. Si vous essayez l'exemple de [khan academy] (http://www.khanacademy.org/computer-programming/tree-generator/822944839), vous remarquerez que le gizmo reste visible pendant que vous tapez. C'est ainsi que fonctionnent tous les auto-finaliseurs, les conseils d'appel, etc. Je ne veux pas vous décourager, mais il faudra * beaucoup * d'efforts pour que cela fonctionne correctement - en particulier la manipulation du clavier. – ekhumoro
@ekhumoro Certainement je ne sous-estime pas la création de ce widget cool :). Cela implique plusieurs choses: 1) la création d'un bon parser glsl, j'ai quelques problèmes à faire fonctionner ce [un] (https://github.com/nicholasbishop/pyglsl_parser) et ce [un] (https: // github .com/rougier/glsl-parser) 2) Maîtriser les possibilités du widget qscintilla (comme vous pouvez le voir je suis loin de le maîtriser) 3) Créer des widgets appropriés pour gérer les types 1/2/3d glsl, je vais créer des widgets pyqt similaires à ceux fournis [ici] (http://editor.thebookofshaders.com/). En tout cas, un petit problème à chaque fois :) – BPL