2016-09-23 7 views
2

Ich habe dieses einfache Stück MCVE Code:Wie zeigen Sie Dialoge an einer bestimmten Position in einem QScintilla-Widget?

import sys 
import re 

from PyQt5 import QtGui, QtWidgets, QtCore 
from PyQt5.Qsci import QsciScintilla 
from PyQt5 import Qsci 


class SimpleEditor(QsciScintilla): 

    def __init__(self, language=None, parent=None): 
     super().__init__(parent) 

     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 on_cursor_position_changed(self, line, index): 
     print("on_cursor_position_changed") 

    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") 


if __name__ == "__main__": 
    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_()) 

Ich versuche, eine ähnliche Lösung mit dem auf dieser site vorgesehen codieren. Wie Sie sehen können, kann der Benutzer auf dieser Seite numerische Werte nur durch Klicken auf "over" ändern, wenn dies der Fall ist, wird ein kleiner Dialog angezeigt und der Benutzer kann Werte in Echtzeit ändern.

Jetzt ist die erste Sache, die ich herausfinden muss, welche Signale ich berücksichtigen muss, wenn der Benutzer auf das QScintilla-Widget klickt (ich verwende diese docs). Welches ist/sind die eine/n, ich sollte mich wirklich darum kümmern.

In jedem Fall, wenn ich das richtige Signal verwende, um mein Dialogfeld mit einigen Schiebereglern zu öffnen, wie könnte ich die richtige Position herausfinden, wo mein Dialog erscheinen sollte?

+0

Was Sie derzeit von Start stoppt, es selbst zu codieren? Fragen zu SO sollten sich auf * ein spezifisches Programmierproblem * konzentrieren - ansonsten sieht es so aus, als würden Sie die Leute bitten, den gesamten Code für Sie zu schreiben. – ekhumoro

+0

@ekhumoro Ok, ich habe meine Hände schmutzig mit der Aufgabe und ich habe meine Frage bearbeitet, um es genauer zu machen, könntest du mir bestätigen, dass das Format jetzt etwas lenkbarer ist? Außerdem habe ich die ganze Menge meiner Offtop-Kommentare losgeworden, damit der Thread nicht verschmutzt wird. Hoffe der Frage Titel/Inhalt sind nicht mehr breit, bitte lass es mich wissen. Vielen Dank. – BPL

+0

Vielen Dank, dass Sie sich die Mühe gemacht haben, Ihre Frage zu verbessern. – ekhumoro

Antwort

2

Das Signal kann verwendet werden, um zu erkennen, wann immer die Maus oder Tastatur den Cursor an eine Position innerhalb einer Nummer bewegt. Ein Regexp kann dann verwendet werden, um zu finden, wo die Nummer in der aktuellen Zeile beginnt und endet. Sobald Sie das haben, können Sie einige Low-Level-Funktionen verwenden, um die globale Position der Zahl zu berechnen.

Die Methode unten verwendet diesen Ansatz ein Tooltip unter dem relevanten Text anzuzeigen:

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 
      break 
    else: 
     point = QtCore.QPoint(0, 0) 
     message = '' 
    QtWidgets.QToolTip.showText(point, message) 
+0

Vielen Dank! Das ist mehr als gut genug, um loszulegen. Der nächste Schritt wird sein, die verschiedenen Widgets zu erstellen, um all die verschiedenen Typen der Sprache (float, vec2, vec3) zu behandeln und sie richtig zu parsen. Übrigens, ein paar zusätzliche schnelle Fragen, weißt du, warum QtWidgets.QColorDialog.getColor() 'anstatt QToolTip mir einen Absturz geben würde? Was ist der beste Weg, um Text auf QScintilla zu ersetzen? Wie auch immer, danke für deine nette Antwort, sehr geschätzt ;-) – BPL

+0

@BPL. Ich denke, dass Sie für diese anderen Fragen einige neue Fragen stellen müssen. – ekhumoro

Verwandte Themen