2016-09-23 77 views
2

我這一段簡單的代碼MCVE:如何在QScintilla小部件的某個位置顯示對話框?

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_()) 

我想編寫一個類似的解決方案,以提供對這個site之一。正如您所看到的,在該網站上,用戶只需通過點擊即可調整數值,當他們這樣做時,會出現一個小對話框,用戶可以實時更改值。

現在,我需要弄清楚的第一件事是當用戶點擊QScintilla小部件時我需要考慮哪些信號(我正在使用這些docs)。哪一個是我應該真正關心的。

在任何情況下,假設我使用正確的信號來彈出包含一些滑塊的對話框,我怎麼才能找出我的對話框應該出現的位置?

+0

目前什麼是阻止你開始自己的代碼呢?關於SO的問題應該關注*一個特定的編程問題* - 否則就好像您要求人們爲您編寫所有代碼。 – ekhumoro

+0

@ekhumoro好吧,我已經把我的雙手弄髒了,我已經編輯了我的問題,試圖使它更具體,你能確認我現在的格式更容易處理嗎?另外,我已經擺脫了一大堆我的offtopic評論,所以線程不會被污染。希望問題標題/內容不再廣泛,請讓我知道。謝謝。 – BPL

+0

謝謝您不厭其煩地改善您的問題。 – ekhumoro

回答

2

cursorPositionChanged信號可用於檢測何時鼠標或鍵盤將插入符號移動到數字中的位置。然後可以使用正則表達式來查找數字在當前行的開始和結束位置。一旦你有了,你可以使用一些低級函數來計算數字的全局位置。

下面的方法使用這種方法來顯示相關的文字下方的工具提示:

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

非常感謝!這遠遠不夠開始。下一步將創建不同的小部件來處理glsl語言提供的所有不同類型(float,vec2,vec3)並正確解析它們。順便說一句,幾個額外的快速問題,你知道爲什麼使用'QtWidgets.QColorDialog.getColor()',而不是QToolTip會給我一個崩潰?另外,什麼是取代QScintilla上文字的最佳方式?無論如何,感謝您的不錯的答案,真的很感激;-) – BPL

+0

@BPL。我想你必須針對其他問題發佈一些新問題。 – ekhumoro

相關問題