2012-03-20 35 views
16

Có một số câu hỏi về SO về điều này, tất cả đều có vẻ như là cách duy nhất để xóa đường viền chấm chấm là to set the focusPolicy on widget/item in question to NoFocus. Trong khi điều này hoạt động như một bản sửa lỗi tạm thời, điều này ngăn cản sự tương tác thêm với tiện ích/mục được cho biết trong lĩnh vực tập trung cần thiết khác.Xóa đường viền chấm chấm mà không đặt NoFocus trong Windows PyQt

Said biên giới trong câu hỏi:

Dotted Focus? Border

Dưới đây là một ví dụ về lý do tại sao điều này không làm việc.

  • Tôi có cửa sổ bật lên tiện ích không phải Modal, hãy nghĩ hộp đèn cho hình ảnh.
  • Tôi muốn phát hiện mousePressEvent bên ngoài tiện ích con và đóng tiện ích con. Để làm điều này, tôi nên catch the focusOutEvent.
  • Tuy nhiên, nếu phần lớn các tiện ích trong chương trình của tôi được đặt là NoFocus (để loại bỏ vấn đề biên giới), thì tôi không thể lấy focusOutEvent vì bạn đoán nó không có chính sách lấy nét.

Dưới đây là một ví dụ khác:

  • Tôi có một QTreeWidget được subclassed vì vậy tôi có thể bắt keyPressEvents vì nhiều lý do.
  • QTreeWidget cũng được đặt làm NoFocus để ngăn đường biên. Bởi vì điều này, tuy nhiên, các widget không bao giờ có tập trung và do đó không có keyPressEvents có thể bị bắt.
  • Giải pháp cho việc này (kludgy, imo) là use the widget's grabKeyboard class, điều này rất nguy hiểm nếu tôi quên phát hànhSau đó sau này. Đây không phải là tối ưu.

Vì vậy, câu hỏi là, có cách nào để xóa đường viền chấm kỳ lạ (chủ yếu là xấu xí) mà không tắt tiêu điểm cho mọi thứ trong ứng dụng của tôi không? Cảm ơn trước!

+0

hệ điều hành gì trên bạn sử dụng? – jdi

+0

Windows (7), tôi sợ. – Cryptite

+0

Sau đó, bạn có thể được delving vào một paintEvent tùy chỉnh: -/ – jdi

Trả lời

37

Đặt outline: 0 của đối tượng mong muốn. Tham khảo ví dụ sau đây đặt nó cho một QTableView.

QTableView 
{ 
    outline: 0; 
} 

Làm việc cho QAbstractItemView các lớp kế thừa. (QTreeWidget, QTableWidget vv). Đáng ngạc nhiên là tài sản CSS này không được đề cập trong Tài liệu QT.Xem QT Style Sheet Reference Documenation.

+5

Thần thánh là tất cả những gì nó cần. Dính vào phong cách QTreeView của bạn và bạn vàng. – Cryptite

+1

Điều này cũng hoạt động cho các lớp kế thừa QAbstractButton, ví dụ: QPushButton, QRadioButton và QCheckBox. Sử dụng nó trong ứng dụng C++ Qt của tôi ngay bây giờ. Tuyệt quá! – Sumyrda

+0

Bạn đã cứu ngày của tôi, điều này đã qpushbutton của tôi đến cấp độ tiếp theo như các nút của tôi là hẹp và các dấu chấm được bao gồm văn bản. Ghi chú nhỏ và rõ ràng cho những người không đọc giữa các dòng, "outline: 0;" được thêm trực tiếp vào thuộc tính qstylesheet của bạn. Cảm ơn! – JavaBeast

3

Trên OSX bạn có thể làm QWidget.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False). Không chắc chắn về Win hoặc Linux. Bạn có thể phải làm điều đó thông qua các bảng định kiểu.

+0

Chỉ cần cho vui thú vị, tôi đã cố gắng thiết lập đó, nhưng như bạn có thể tưởng tượng rằng không có gì cho tôi trong Windows. Tôi đã đi trước và đặt một tiền thưởng trong một nỗ lực để thu hút sự chú ý nhiều hơn đến điều này. Cảm ơn bạn đã giúp đỡ jdi trong mọi trường hợp. Ứng dụng tôi đang viết sẽ có cổng Mac sớm hơn sau này, vì vậy điều này sẽ vẫn hữu ích. – Cryptite

1

Hầu hết các kiểu chỉ định bản vẽ chỉ báo tiêu điểm cho hàm QStyle::drawPrimitive với PE_FrameFocusRect làm phần tử được vẽ.

Vì vậy, bạn sẽ có thể vô hiệu hóa trên toàn cầu với lớp phong cách sau đây được cài đặt trên các ví dụ ứng dụng:

class NoFocusProxyStyle : public QProxyStyle { 
public: 

    NoFocusProxyStyle(QStyle *baseStyle = 0) : QProxyStyle(baseStyle) {} 

    void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { 
     if(element == QStyle::PE_FrameFocusRect) { 
      return; 
     } 
     QProxyStyle::drawPrimitive(element, option, painter, widget); 
    } 

}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv);  
    a.setStyle(new NoFocusProxyStyle); 
    ... 

PS: Nó không làm việc với QGtkStyle đối với một số widget (nút, combobox), do đó nó có thể không hoạt động với Windows hoặc Mac.

+0

Tôi sẽ phải xem nếu tôi không thể chuyển đổi nó thành python cho PyQT, nhưng tôi sẽ cung cấp cho nó một shot. – Cryptite

+0

@Cryptite: nó không hoạt động với PyQt (hoặc PySide) vì lớp 'QProxyStyle' không được xuất trong python. Và kể từ khi các kiểu cụ thể ('QWindowsStyle',' QWindowsXPStyle' ...) không được xuất, bạn không thể ghi đè hàm đó theo kiểu hiện tại (tôi cũng đã cố gắng vá khỉ, thay thế drawPrimitive trên 'QApplication.style() ', nhưng tôi không thực sự chắc chắn nếu tôi đã làm nó một cách chính xác). – alexisdm

+0

Vì vậy, cốt truyện dày lên. Phải có một số cách để đạt được điều này. Ai đó trong bóng tối của interwebs hẳn đã giải quyết được vấn đề này. – Cryptite

0

Bạn có thể làm điều này với PyQt5:

class Style(QProxyStyle): 
    def drawPrimitive(self, element, option, painter, widget): 
     if element == QStyle.PE_FrameFocusRect: 
      return 
     super().drawPrimitive(element, option, painter, widget) 

app.setStyle(Style()) 
+0

Đây không phải là một giải pháp tuyệt vời vì nó làm cho QTableWidget tụt hậu đáng kể. – Kermit

Các vấn đề liên quan